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