Seastar
High performance C++ framework for concurrent servers
api.hh
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/temporary_buffer.hh>
32 #include <seastar/core/iostream.hh>
33 #include <seastar/util/std-compat.hh>
34 #include "../core/internal/api-level.hh"
35 #include <sys/types.h>
36 
37 namespace seastar {
38 
39 inline
40 bool is_ip_unspecified(const ipv4_addr& addr) noexcept {
41  return addr.is_ip_unspecified();
42 }
43 
44 inline
45 bool is_port_unspecified(const ipv4_addr& addr) noexcept {
46  return addr.is_port_unspecified();
47 }
48 
49 inline
50 socket_address make_ipv4_address(const ipv4_addr& addr) noexcept {
51  return socket_address(addr);
52 }
53 
54 inline
55 socket_address make_ipv4_address(uint32_t ip, uint16_t port) noexcept {
56  return make_ipv4_address(ipv4_addr(ip, port));
57 }
58 
59 namespace net {
60 
61 // see linux tcp(7) for parameter explanation
63  std::chrono::seconds idle; // TCP_KEEPIDLE
64  std::chrono::seconds interval; // TCP_KEEPINTVL
65  unsigned count; // TCP_KEEPCNT
66 };
67 
68 // see linux sctp(7) for parameter explanation
70  std::chrono::seconds interval; // spp_hbinterval
71  unsigned count; // spp_pathmaxrt
72 };
73 
74 using keepalive_params = std::variant<tcp_keepalive_params, sctp_keepalive_params>;
75 
77 class connected_socket_impl;
78 class socket_impl;
79 
80 class server_socket_impl;
81 class udp_channel_impl;
82 class get_impl;
84 
86 public:
87  virtual ~udp_datagram_impl() {};
88  virtual socket_address get_src() = 0;
89  virtual socket_address get_dst() = 0;
90  virtual uint16_t get_dst_port() = 0;
91  virtual packet& get_data() = 0;
92 };
93 
94 class udp_datagram final {
95 private:
96  std::unique_ptr<udp_datagram_impl> _impl;
97 public:
98  udp_datagram(std::unique_ptr<udp_datagram_impl>&& impl) noexcept : _impl(std::move(impl)) {};
99  socket_address get_src() { return _impl->get_src(); }
100  socket_address get_dst() { return _impl->get_dst(); }
101  uint16_t get_dst_port() { return _impl->get_dst_port(); }
102  packet& get_data() { return _impl->get_data(); }
103 };
104 
105 class udp_channel {
106 private:
107  std::unique_ptr<udp_channel_impl> _impl;
108 public:
109  udp_channel() noexcept;
110  udp_channel(std::unique_ptr<udp_channel_impl>) noexcept;
111  ~udp_channel();
112 
113  udp_channel(udp_channel&&) noexcept;
114  udp_channel& operator=(udp_channel&&) noexcept;
115 
116  socket_address local_address() const;
117 
118  future<udp_datagram> receive();
119  future<> send(const socket_address& dst, const char* msg);
120  future<> send(const socket_address& dst, packet p);
121  bool is_closed() const;
131  void close();
132 };
133 
134 class network_interface_impl;
135 
136 } /* namespace net */
137 
140 
149  unsigned buffer_size = 8192;
153  unsigned min_buffer_size = 512;
157  unsigned max_buffer_size = 128 * 1024;
158 };
159 
165  friend class net::get_impl;
166  std::unique_ptr<net::connected_socket_impl> _csi;
167 public:
169  connected_socket() noexcept;
170  ~connected_socket();
171 
173  explicit connected_socket(std::unique_ptr<net::connected_socket_impl> csi) noexcept;
178  connected_socket& operator=(connected_socket&& cs) noexcept;
189  output_stream<char> output(size_t buffer_size = 8192);
191  void set_nodelay(bool nodelay);
195  bool get_nodelay() const;
197  void set_keepalive(bool keepalive);
200  bool get_keepalive() const;
202  void set_keepalive_parameters(const net::keepalive_params& p);
204  net::keepalive_params get_keepalive_parameters() const;
208  void set_sockopt(int level, int optname, const void* data, size_t len);
212  int get_sockopt(int level, int optname, void* data, size_t len) const;
213 
227 };
229 
232 
237 class socket {
238  std::unique_ptr<net::socket_impl> _si;
239 public:
240  socket() noexcept = default;
241  ~socket();
242 
244  explicit socket(std::unique_ptr<net::socket_impl> si) noexcept;
247  socket(socket&&) noexcept;
249  socket& operator=(socket&&) noexcept;
250 
254  future<connected_socket> connect(socket_address sa, socket_address local = {}, transport proto = transport::TCP);
255 
257  void set_reuseaddr(bool reuseaddr);
260  bool get_reuseaddr() const;
265  void shutdown();
266 };
267 
269 
272 
277 };
278 
281  std::unique_ptr<net::server_socket_impl> _ssi;
282  bool _aborted = false;
283 public:
284  enum class load_balancing_algorithm {
285  // This algorithm tries to distribute all connections equally between all shards.
286  // It does this by sending new connections to a shard with smallest amount of connections.
287  connection_distribution,
288  // This algorithm distributes new connection based on peer's tcp port. Destination shard
289  // is calculated as a port number modulo number of shards. This allows a client to connect
290  // to a specific shard in a server given it knows how many shards server has by choosing
291  // src port number accordingly.
292  port,
293  // This algorithm distributes all new connections to listen_options::fixed_cpu shard only.
294  fixed,
295  default_ = connection_distribution
296  };
298  server_socket() noexcept;
300  explicit server_socket(std::unique_ptr<net::server_socket_impl> ssi) noexcept;
303  server_socket(server_socket&& ss) noexcept;
304  ~server_socket();
306  server_socket& operator=(server_socket&& cs) noexcept;
307 
316 
321  void abort_accept();
322 
324  socket_address local_address() const noexcept;
325 };
326 
328 
330  bool reuse_address = false;
331  server_socket::load_balancing_algorithm lba = server_socket::load_balancing_algorithm::default_;
332  transport proto = transport::TCP;
333  int listen_backlog = 100;
334  unsigned fixed_cpu = 0u;
335  void set_fixed_cpu(unsigned cpu) {
336  lba = server_socket::load_balancing_algorithm::fixed;
337  fixed_cpu = cpu;
338  }
339 };
340 
342 private:
344 public:
345  network_interface() = delete;
348 
350 
351  uint32_t index() const;
352  uint32_t mtu() const;
353 
354  const sstring& name() const;
355  const sstring& display_name() const;
356  const std::vector<net::inet_address>& addresses() const;
357  const std::vector<uint8_t> hardware_address() const;
358 
359  bool is_loopback() const;
360  bool is_virtual() const;
361  bool is_up() const;
362  bool supports_ipv6() const;
363 };
364 
366 public:
367  virtual ~network_stack() {}
368  virtual server_socket listen(socket_address sa, listen_options opts) = 0;
369  // FIXME: local parameter assumes ipv4 for now, fix when adding other AF
370  future<connected_socket> connect(socket_address sa, socket_address = {}, transport proto = transport::TCP);
371  virtual ::seastar::socket socket() = 0;
372  virtual net::udp_channel make_udp_channel(const socket_address& = {}) = 0;
373  virtual future<> initialize() {
374  return make_ready_future();
375  }
376  virtual bool has_per_core_namespace() = 0;
377  // NOTE: this is not a correct query approach.
378  // This question should be per NIC, but we have no such
379  // abstraction, so for now this is "stack-wide"
380  virtual bool supports_ipv6() const {
381  return false;
382  }
383 
389  virtual std::vector<network_interface> network_interfaces();
390 };
391 
392 }
seastar::listen
server_socket listen(socket_address sa)
seastar::shared_ptr< net::network_interface_impl >
seastar::net::sctp_keepalive_params
Definition: api.hh:69
seastar::connected_socket::shutdown_input
void shutdown_input()
seastar::net::udp_datagram
Definition: api.hh:94
seastar
Seastar API namespace.
Definition: abort_on_ebadf.hh:24
seastar::connected_socket_input_stream_config::min_buffer_size
unsigned min_buffer_size
Definition: api.hh:153
seastar::net::udp_channel::shutdown_output
void shutdown_output()
Causes a pending send() to complete (possibly with an exception)
seastar::make_ready_future
future< T... > make_ready_future(A &&... value) noexcept
Creates a future in an available, value state.
Definition: future.hh:2048
seastar::net::packet
Definition: packet.hh:79
seastar::connected_socket::get_sockopt
int get_sockopt(int level, int optname, void *data, size_t len) const
seastar::connected_socket::set_keepalive_parameters
void set_keepalive_parameters(const net::keepalive_params &p)
Sets TCP keepalive parameters.
seastar::connected_socket_input_stream_config::buffer_size
unsigned buffer_size
Initial buffer size to use for input buffering.
Definition: api.hh:149
seastar::socket
Definition: api.hh:237
seastar::net::udp_channel::close
void close()
seastar::input_stream
Definition: iostream.hh:200
seastar::connected_socket::connected_socket
connected_socket() noexcept
Constructs a connected_socket not corresponding to a connection.
seastar::socket::shutdown
void shutdown()
seastar::server_socket::operator=
server_socket & operator=(server_socket &&cs) noexcept
Move-assigns a server_socket object.
seastar::network_interface
Definition: api.hh:341
seastar::connected_socket::get_nodelay
bool get_nodelay() const
seastar::connected_socket
Definition: api.hh:164
seastar::socket::set_reuseaddr
void set_reuseaddr(bool reuseaddr)
Sets SO_REUSEADDR option (enable reuseaddr option on a socket)
seastar::connected_socket_input_stream_config::max_buffer_size
unsigned max_buffer_size
Definition: api.hh:157
seastar::connected_socket::input
input_stream< char > input(connected_socket_input_stream_config csisc={})
seastar::connected_socket::get_keepalive_parameters
net::keepalive_params get_keepalive_parameters() const
Get TCP keepalive parameters.
seastar::connected_socket::output
output_stream< char > output(size_t buffer_size=8192)
seastar::net::udp_channel
Definition: api.hh:105
seastar::server_socket
A listening socket, waiting to accept incoming network connections.
Definition: api.hh:280
seastar::net::udp_channel::shutdown_input
void shutdown_input()
Causes a pending receive() to complete (possibly with an exception)
seastar::accept_result::connection
connected_socket connection
The newly-accepted connection.
Definition: api.hh:275
seastar::server_socket::local_address
socket_address local_address() const noexcept
Local bound address.
seastar::server_socket::abort_accept
void abort_accept()
seastar::connected_socket::shutdown_output
void shutdown_output()
seastar::net::udp_datagram_impl
Definition: api.hh:85
seastar::accept_result
The result of an server_socket::accept() call.
Definition: api.hh:274
seastar::server_socket::accept
future< accept_result > accept()
seastar::connected_socket::set_nodelay
void set_nodelay(bool nodelay)
Sets the TCP_NODELAY option (disabling Nagle's algorithm)
seastar::connect
future< connected_socket > connect(socket_address sa)
seastar::connected_socket_input_stream_config
Definition: api.hh:147
seastar::future
A representation of a possibly not-yet-computed value.
Definition: future.hh:1337
seastar::socket::get_reuseaddr
bool get_reuseaddr() const
seastar::server_socket::server_socket
server_socket() noexcept
Constructs a server_socket not corresponding to a connection.
seastar::listen_options
Definition: api.hh:329
impl
holds the implementation parts of the metrics layer, do not use directly.
seastar::connected_socket::get_keepalive
bool get_keepalive() const
seastar::socket::connect
future< connected_socket > connect(socket_address sa, socket_address local={}, transport proto=transport::TCP)
seastar::net::tcp_keepalive_params
Definition: api.hh:62
seastar::connected_socket::set_sockopt
void set_sockopt(int level, int optname, const void *data, size_t len)
seastar::socket::socket
socket(socket &&) noexcept
Moves a seastar::socket object.
seastar::output_stream< char >
seastar::socket_address
Definition: socket_defs.hh:41
seastar::make_udp_channel
net::udp_channel make_udp_channel()
seastar::accept_result::remote_address
socket_address remote_address
The address of the peer that connected to us.
Definition: api.hh:276
seastar::network_stack
Definition: api.hh:365
seastar::network_stack::network_interfaces
virtual std::vector< network_interface > network_interfaces()
seastar::connected_socket::set_keepalive
void set_keepalive(bool keepalive)
Sets SO_KEEPALIVE option (enable keepalive timer on a socket)