]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/include/seastar/net/api.hh
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / include / seastar / net / api.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 <memory>
25#include <vector>
26#include <cstring>
27#include <seastar/core/future.hh>
28#include <seastar/net/byteorder.hh>
29#include <seastar/net/socket_defs.hh>
30#include <seastar/net/packet.hh>
31#include <seastar/core/print.hh>
32#include <seastar/core/temporary_buffer.hh>
33#include <seastar/core/iostream.hh>
34#include <seastar/util/std-compat.hh>
35#include <sys/types.h>
36
37namespace seastar {
38
39static inline
40bool is_ip_unspecified(ipv4_addr &addr) {
41 return addr.ip == 0;
42}
43
44static inline
45bool is_port_unspecified(ipv4_addr &addr) {
46 return addr.port == 0;
47}
48
49static inline
50std::ostream& operator<<(std::ostream &os, ipv4_addr addr) {
51 fmt_print(os, "{:d}.{:d}.{:d}.{:d}",
52 (addr.ip >> 24) & 0xff,
53 (addr.ip >> 16) & 0xff,
54 (addr.ip >> 8) & 0xff,
55 (addr.ip) & 0xff);
56 return os << ":" << addr.port;
57}
58
59static inline
60socket_address make_ipv4_address(ipv4_addr addr) {
61 socket_address sa;
62 sa.u.in.sin_family = AF_INET;
63 sa.u.in.sin_port = htons(addr.port);
64 sa.u.in.sin_addr.s_addr = htonl(addr.ip);
65 return sa;
66}
67
68inline
69socket_address make_ipv4_address(uint32_t ip, uint16_t port) {
70 socket_address sa;
71 sa.u.in.sin_family = AF_INET;
72 sa.u.in.sin_port = htons(port);
73 sa.u.in.sin_addr.s_addr = htonl(ip);
74 return sa;
75}
76
77namespace net {
78
79// see linux tcp(7) for parameter explanation
80struct tcp_keepalive_params {
81 std::chrono::seconds idle; // TCP_KEEPIDLE
82 std::chrono::seconds interval; // TCP_KEEPINTVL
83 unsigned count; // TCP_KEEPCNT
84};
85
86// see linux sctp(7) for parameter explanation
87struct sctp_keepalive_params {
88 std::chrono::seconds interval; // spp_hbinterval
89 unsigned count; // spp_pathmaxrt
90};
91
92using keepalive_params = compat::variant<tcp_keepalive_params, sctp_keepalive_params>;
93
94/// \cond internal
95class connected_socket_impl;
96class socket_impl;
97class server_socket_impl;
98class udp_channel_impl;
99class get_impl;
100/// \endcond
101
102class udp_datagram_impl {
103public:
104 virtual ~udp_datagram_impl() {};
105 virtual ipv4_addr get_src() = 0;
106 virtual ipv4_addr get_dst() = 0;
107 virtual uint16_t get_dst_port() = 0;
108 virtual packet& get_data() = 0;
109};
110
111class udp_datagram final {
112private:
113 std::unique_ptr<udp_datagram_impl> _impl;
114public:
115 udp_datagram(std::unique_ptr<udp_datagram_impl>&& impl) : _impl(std::move(impl)) {};
116 ipv4_addr get_src() { return _impl->get_src(); }
117 ipv4_addr get_dst() { return _impl->get_dst(); }
118 uint16_t get_dst_port() { return _impl->get_dst_port(); }
119 packet& get_data() { return _impl->get_data(); }
120};
121
122class udp_channel {
123private:
124 std::unique_ptr<udp_channel_impl> _impl;
125public:
126 udp_channel();
127 udp_channel(std::unique_ptr<udp_channel_impl>);
128 ~udp_channel();
129
130 udp_channel(udp_channel&&);
131 udp_channel& operator=(udp_channel&&);
132
133 future<udp_datagram> receive();
134 future<> send(ipv4_addr dst, const char* msg);
135 future<> send(ipv4_addr dst, packet p);
136 bool is_closed() const;
137 /// Causes a pending receive() to complete (possibly with an exception)
138 void shutdown_input();
139 /// Causes a pending send() to complete (possibly with an exception)
140 void shutdown_output();
141 /// Close the channel and releases all resources.
142 ///
143 /// Must be called only when there are no unfinished send() or receive() calls. You
144 /// can force pending calls to complete soon by calling shutdown_input() and
145 /// shutdown_output().
146 void close();
147};
148
149} /* namespace net */
150
151/// \addtogroup networking-module
152/// @{
153
154/// A TCP (or other stream-based protocol) connection.
155///
156/// A \c connected_socket represents a full-duplex stream between
157/// two endpoints, a local endpoint and a remote endpoint.
158class connected_socket {
159 friend class net::get_impl;
160 std::unique_ptr<net::connected_socket_impl> _csi;
161public:
162 /// Constructs a \c connected_socket not corresponding to a connection
163 connected_socket();
164 ~connected_socket();
165
166 /// \cond internal
167 explicit connected_socket(std::unique_ptr<net::connected_socket_impl> csi);
168 /// \endcond
169 /// Moves a \c connected_socket object.
170 connected_socket(connected_socket&& cs) noexcept;
171 /// Move-assigns a \c connected_socket object.
172 connected_socket& operator=(connected_socket&& cs) noexcept;
173 /// Gets the input stream.
174 ///
175 /// Gets an object returning data sent from the remote endpoint.
176 input_stream<char> input();
177 /// Gets the output stream.
178 ///
179 /// Gets an object that sends data to the remote endpoint.
180 /// \param buffer_size how much data to buffer
181 output_stream<char> output(size_t buffer_size = 8192);
182 /// Sets the TCP_NODELAY option (disabling Nagle's algorithm)
183 void set_nodelay(bool nodelay);
184 /// Gets the TCP_NODELAY option (Nagle's algorithm)
185 ///
186 /// \return whether the nodelay option is enabled or not
187 bool get_nodelay() const;
188 /// Sets SO_KEEPALIVE option (enable keepalive timer on a socket)
189 void set_keepalive(bool keepalive);
190 /// Gets O_KEEPALIVE option
191 /// \return whether the keepalive option is enabled or not
192 bool get_keepalive() const;
193 /// Sets TCP keepalive parameters
194 void set_keepalive_parameters(const net::keepalive_params& p);
195 /// Get TCP keepalive parameters
196 net::keepalive_params get_keepalive_parameters() const;
197
198 /// Disables output to the socket.
199 ///
200 /// Current or future writes that have not been successfully flushed
201 /// will immediately fail with an error. This is useful to abort
202 /// operations on a socket that is not making progress due to a
203 /// peer failure.
204 void shutdown_output();
205 /// Disables input from the socket.
206 ///
207 /// Current or future reads will immediately fail with an error.
208 /// This is useful to abort operations on a socket that is not making
209 /// progress due to a peer failure.
210 void shutdown_input();
211};
212/// @}
213
214/// \addtogroup networking-module
215/// @{
216
217/// The seastar socket.
218///
219/// A \c socket that allows a connection to be established between
220/// two endpoints.
221class socket {
222 std::unique_ptr<net::socket_impl> _si;
223public:
224 ~socket();
225
226 /// \cond internal
227 explicit socket(std::unique_ptr<net::socket_impl> si);
228 /// \endcond
229 /// Moves a \c seastar::socket object.
230 socket(socket&&) noexcept;
231 /// Move-assigns a \c seastar::socket object.
232 socket& operator=(socket&&) noexcept;
233
234 /// Attempts to establish the connection.
235 ///
236 /// \return a \ref connected_socket representing the connection.
237 future<connected_socket> connect(socket_address sa, socket_address local = socket_address(::sockaddr_in{AF_INET, INADDR_ANY, {0}}), transport proto = transport::TCP);
238 /// Stops any in-flight connection attempt.
239 ///
240 /// Cancels the connection attempt if it's still in progress, and
241 /// terminates the connection if it has already been established.
242 void shutdown();
243};
244
245/// @}
246
247/// \addtogroup networking-module
248/// @{
249
250/// A listening socket, waiting to accept incoming network connections.
251class server_socket {
252 std::unique_ptr<net::server_socket_impl> _ssi;
253 bool _aborted = false;
254public:
255 enum class load_balancing_algorithm {
256 // This algorithm tries to distribute all connections equally between all shards.
257 // It does this by sending new connections to a shard with smallest amount of connections.
258 connection_distribution,
259 // This algorithm distributes new connection based on peer's tcp port. Destination shard
260 // is calculated as a port number modulo number of shards. This allows a client to connect
261 // to a specific shard in a server given it knows how many shards server has by choosing
262 // src port number accordingly.
263 port,
264 default_ = connection_distribution
265 };
266 /// Constructs a \c server_socket not corresponding to a connection
267 server_socket();
268 /// \cond internal
269 explicit server_socket(std::unique_ptr<net::server_socket_impl> ssi);
270 /// \endcond
271 /// Moves a \c server_socket object.
272 server_socket(server_socket&& ss) noexcept;
273 ~server_socket();
274 /// Move-assigns a \c server_socket object.
275 server_socket& operator=(server_socket&& cs) noexcept;
276
277 /// Accepts the next connection to successfully connect to this socket.
278 ///
279 /// \return a \ref connected_socket representing the connection, and
280 /// a \ref socket_address describing the remote endpoint.
281 ///
282 /// \see listen(socket_address sa)
283 /// \see listen(socket_address sa, listen_options opts)
284 future<connected_socket, socket_address> accept();
285
286 /// Stops any \ref accept() in progress.
287 ///
288 /// Current and future \ref accept() calls will terminate immediately
289 /// with an error.
290 void abort_accept();
291};
292/// @}
293
294struct listen_options {
295 bool reuse_address = false;
296 server_socket::load_balancing_algorithm lba = server_socket::load_balancing_algorithm::default_;
297 transport proto = transport::TCP;
298};
299
300class network_stack {
301public:
302 virtual ~network_stack() {}
303 virtual server_socket listen(socket_address sa, listen_options opts) = 0;
304 // FIXME: local parameter assumes ipv4 for now, fix when adding other AF
305 future<connected_socket> connect(socket_address sa, socket_address local = socket_address(::sockaddr_in{AF_INET, INADDR_ANY, {0}}), transport proto = transport::TCP) {
306 return do_with(socket(), [sa, local, proto](::seastar::socket& s) {
307 return s.connect(sa, local, proto);
308 });
309 }
310 virtual ::seastar::socket socket() = 0;
311 virtual net::udp_channel make_udp_channel(ipv4_addr addr = {}) = 0;
312 virtual future<> initialize() {
313 return make_ready_future();
314 }
315 virtual bool has_per_core_namespace() = 0;
316};
317
318}