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
36namespace seastar {
37
38SEASTAR_MODULE_EXPORT_BEGIN
39
40namespace net {
41class inet_address;
42}
43
44struct ipv4_addr;
45struct ipv6_addr;
46
48public:
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
106std::ostream& operator<<(std::ostream&, const socket_address&);
107
108enum class transport {
109 TCP = IPPROTO_TCP,
110 SCTP = IPPROTO_SCTP
111};
112
113struct 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
136struct 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
158std::ostream& operator<<(std::ostream&, const ipv4_addr&);
159std::ostream& operator<<(std::ostream&, const ipv6_addr&);
160
161inline bool operator==(const ipv4_addr &lhs, const ipv4_addr& rhs) noexcept {
162 return lhs.ip == rhs.ip && lhs.port == rhs.port;
163}
164SEASTAR_MODULE_EXPORT_END
165}
166
167namespace std {
168template<>
169struct hash<seastar::socket_address> {
170 size_t operator()(const seastar::socket_address&) const;
171};
172template<>
173struct hash<seastar::ipv4_addr> {
174 size_t operator()(const seastar::ipv4_addr&) const;
175};
176template<>
177struct hash<seastar::unix_domain_addr> {
178 size_t operator()(const seastar::unix_domain_addr&) const;
179};
180template<>
181struct hash<::sockaddr_un> {
182 size_t operator()(const ::sockaddr_un&) const;
183};
184
185template <>
186struct 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
195template <> struct fmt::formatter<seastar::socket_address> : fmt::ostream_formatter {};
196template <> struct fmt::formatter<seastar::ipv4_addr> : fmt::ostream_formatter {};
197template <> struct fmt::formatter<seastar::ipv6_addr> : fmt::ostream_formatter {};
198#endif
Definition: inet_address.hh:50
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
STL namespace.
Definition: socket_defs.hh:113
Definition: socket_defs.hh:136
Definition: unix_address.hh:43