Seastar
High performance C++ framework for concurrent servers
socket_defs.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) 2016 ScyllaDB.
20  */
21 #pragma once
22 
23 #ifndef SEASTAR_MODULE
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <netinet/ip.h>
27 #include <array>
28 #include <cassert>
29 #include <functional>
30 #include <iosfwd>
31 #include <fmt/ostream.h>
32 #endif
33 #include <seastar/net/byteorder.hh>
34 #include <seastar/net/unix_address.hh>
35 
36 namespace seastar {
37 
38 SEASTAR_MODULE_EXPORT_BEGIN
39 
40 namespace net {
41 class inet_address;
42 }
43 
44 struct ipv4_addr;
45 struct ipv6_addr;
46 
48 public:
49  socklen_t addr_length;
50  union {
51  ::sockaddr_storage sas;
52  ::sockaddr sa;
53  ::sockaddr_in in;
54  ::sockaddr_in6 in6;
55  ::sockaddr_un un;
56  } u;
57  socket_address(const sockaddr_in& sa) noexcept : addr_length{sizeof(::sockaddr_in)} {
58  u.in = sa;
59  }
60  socket_address(const sockaddr_in6& sa) noexcept : addr_length{sizeof(::sockaddr_in6)} {
61  u.in6 = sa;
62  }
63  socket_address(uint16_t) noexcept;
64  socket_address(ipv4_addr) noexcept;
65  socket_address(const ipv6_addr&) noexcept;
66  socket_address(const ipv6_addr&, uint32_t scope) noexcept;
67  socket_address(const net::inet_address&, uint16_t p = 0) noexcept;
68  explicit socket_address(const unix_domain_addr&) noexcept;
73  socket_address() noexcept;
74 
75  ::sockaddr& as_posix_sockaddr() noexcept { return u.sa; }
76  ::sockaddr_in& as_posix_sockaddr_in() noexcept { return u.in; }
77  ::sockaddr_in6& as_posix_sockaddr_in6() noexcept { return u.in6; }
78  const ::sockaddr& as_posix_sockaddr() const noexcept { return u.sa; }
79  const ::sockaddr_in& as_posix_sockaddr_in() const noexcept { return u.in; }
80  const ::sockaddr_in6& as_posix_sockaddr_in6() const noexcept { return u.in6; }
81 
82  socket_address(uint32_t, uint16_t p = 0) noexcept;
83 
84  socklen_t length() const noexcept { return addr_length; };
85 
86  bool is_af_unix() const noexcept {
87  return u.sa.sa_family == AF_UNIX;
88  }
89 
90  bool is_unspecified() const noexcept;
91 
92  sa_family_t family() const noexcept {
93  return u.sa.sa_family;
94  }
95 
96  net::inet_address addr() const noexcept;
97  ::in_port_t port() const noexcept;
98  bool is_wildcard() const noexcept;
99 
100  bool operator==(const socket_address&) const noexcept;
101  bool operator!=(const socket_address& a) const noexcept {
102  return !(*this == a);
103  }
104 };
105 
106 std::ostream& operator<<(std::ostream&, const socket_address&);
107 
108 enum class transport {
109  TCP = IPPROTO_TCP,
110  SCTP = IPPROTO_SCTP
111 };
112 
113 struct ipv4_addr {
114  uint32_t ip;
115  uint16_t port;
116 
117  ipv4_addr() noexcept : ip(0), port(0) {}
118  ipv4_addr(uint32_t ip, uint16_t port) noexcept : ip(ip), port(port) {}
119  ipv4_addr(uint16_t port) noexcept : ip(0), port(port) {}
120  // throws if not a valid ipv4 addr
121  ipv4_addr(const std::string &addr);
122  ipv4_addr(const std::string &addr, uint16_t port);
123  // throws if not an ipv4 addr
124  ipv4_addr(const net::inet_address&, uint16_t);
125  ipv4_addr(const socket_address &) noexcept;
126  ipv4_addr(const ::in_addr&, uint16_t = 0) noexcept;
127 
128  bool is_ip_unspecified() const noexcept {
129  return ip == 0;
130  }
131  bool is_port_unspecified() const noexcept {
132  return port == 0;
133  }
134 };
135 
136 struct ipv6_addr {
137  using ipv6_bytes = std::array<uint8_t, 16>;
138 
139  ipv6_bytes ip;
140  uint16_t port;
141 
142  ipv6_addr(const ipv6_bytes&, uint16_t port = 0) noexcept;
143  ipv6_addr(uint16_t port = 0) noexcept;
144  // throws if not a valid ipv6 addr
145  ipv6_addr(const std::string&);
146  ipv6_addr(const std::string&, uint16_t port);
147  ipv6_addr(const net::inet_address&, uint16_t = 0) noexcept;
148  ipv6_addr(const ::in6_addr&, uint16_t = 0) noexcept;
149  ipv6_addr(const ::sockaddr_in6&) noexcept;
150  ipv6_addr(const socket_address&) noexcept;
151 
152  bool is_ip_unspecified() const noexcept;
153  bool is_port_unspecified() const noexcept {
154  return port == 0;
155  }
156 };
157 
158 std::ostream& operator<<(std::ostream&, const ipv4_addr&);
159 std::ostream& operator<<(std::ostream&, const ipv6_addr&);
160 
161 inline bool operator==(const ipv4_addr &lhs, const ipv4_addr& rhs) noexcept {
162  return lhs.ip == rhs.ip && lhs.port == rhs.port;
163 }
164 SEASTAR_MODULE_EXPORT_END
165 }
166 
167 namespace std {
168 template<>
169 struct hash<seastar::socket_address> {
170  size_t operator()(const seastar::socket_address&) const;
171 };
172 template<>
173 struct hash<seastar::ipv4_addr> {
174  size_t operator()(const seastar::ipv4_addr&) const;
175 };
176 template<>
177 struct hash<seastar::unix_domain_addr> {
178  size_t operator()(const seastar::unix_domain_addr&) const;
179 };
180 template<>
181 struct hash<::sockaddr_un> {
182  size_t operator()(const ::sockaddr_un&) const;
183 };
184 
185 template <>
186 struct hash<seastar::transport> {
187  size_t operator()(seastar::transport tr) const {
188  return static_cast<size_t>(tr);
189  }
190 };
191 
192 }
193 
194 #if FMT_VERSION >= 90000
195 template <> struct fmt::formatter<seastar::socket_address> : fmt::ostream_formatter {};
196 template <> struct fmt::formatter<seastar::ipv4_addr> : fmt::ostream_formatter {};
197 template <> struct fmt::formatter<seastar::ipv6_addr> : fmt::ostream_formatter {};
198 #endif
Definition: inet_address.hh:49
Definition: socket_defs.hh:47
union seastar::socket_address::@14 u
!< actual size of the relevant 'u' member
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Definition: socket_defs.hh:113
Definition: socket_defs.hh:136
Definition: unix_address.hh:43