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