]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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> | |
9f95a23c | 24 | #include <array> |
11fdf7f2 | 25 | #include <sys/socket.h> |
9f95a23c | 26 | #include <sys/un.h> |
11fdf7f2 TL |
27 | #include <netinet/ip.h> |
28 | #include <seastar/net/byteorder.hh> | |
9f95a23c TL |
29 | #include <seastar/net/unix_address.hh> |
30 | #include <cassert> | |
11fdf7f2 TL |
31 | |
32 | namespace seastar { | |
33 | ||
9f95a23c TL |
34 | namespace net { |
35 | class inet_address; | |
36 | } | |
37 | ||
11fdf7f2 | 38 | struct ipv4_addr; |
9f95a23c | 39 | struct ipv6_addr; |
11fdf7f2 TL |
40 | |
41 | class socket_address { | |
42 | public: | |
9f95a23c | 43 | socklen_t addr_length; ///!< actual size of the relevant 'u' member |
11fdf7f2 TL |
44 | union { |
45 | ::sockaddr_storage sas; | |
46 | ::sockaddr sa; | |
47 | ::sockaddr_in in; | |
9f95a23c TL |
48 | ::sockaddr_in6 in6; |
49 | ::sockaddr_un un; | |
11fdf7f2 | 50 | } u; |
f67539c2 | 51 | socket_address(const sockaddr_in& sa) noexcept : addr_length{sizeof(::sockaddr_in)} { |
11fdf7f2 TL |
52 | u.in = sa; |
53 | } | |
f67539c2 | 54 | socket_address(const sockaddr_in6& sa) noexcept : addr_length{sizeof(::sockaddr_in6)} { |
9f95a23c TL |
55 | u.in6 = sa; |
56 | } | |
f67539c2 TL |
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; | |
9f95a23c TL |
63 | /** creates an uninitialized socket_address. this can be written into, or used as |
64 | * "unspecified" for such addresses as bind(addr) or local address in socket::connect | |
65 | * (i.e. system picks) | |
66 | */ | |
f67539c2 | 67 | socket_address() noexcept; |
9f95a23c | 68 | |
f67539c2 TL |
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; } | |
9f95a23c | 75 | |
f67539c2 | 76 | socket_address(uint32_t, uint16_t p = 0) noexcept; |
9f95a23c | 77 | |
f67539c2 | 78 | socklen_t length() const noexcept { return addr_length; }; |
9f95a23c | 79 | |
f67539c2 | 80 | bool is_af_unix() const noexcept { |
9f95a23c TL |
81 | return u.sa.sa_family == AF_UNIX; |
82 | } | |
83 | ||
f67539c2 | 84 | bool is_unspecified() const noexcept; |
9f95a23c | 85 | |
f67539c2 | 86 | sa_family_t family() const noexcept { |
9f95a23c TL |
87 | return u.sa.sa_family; |
88 | } | |
89 | ||
f67539c2 TL |
90 | net::inet_address addr() const noexcept; |
91 | ::in_port_t port() const noexcept; | |
92 | bool is_wildcard() const noexcept; | |
11fdf7f2 | 93 | |
f67539c2 TL |
94 | bool operator==(const socket_address&) const noexcept; |
95 | bool operator!=(const socket_address& a) const noexcept { | |
9f95a23c TL |
96 | return !(*this == a); |
97 | } | |
11fdf7f2 TL |
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 | ||
11fdf7f2 TL |
107 | struct ipv4_addr { |
108 | uint32_t ip; | |
109 | uint16_t port; | |
110 | ||
f67539c2 TL |
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 | |
11fdf7f2 TL |
115 | ipv4_addr(const std::string &addr); |
116 | ipv4_addr(const std::string &addr, uint16_t port); | |
f67539c2 | 117 | // throws if not an ipv4 addr |
11fdf7f2 | 118 | ipv4_addr(const net::inet_address&, uint16_t); |
f67539c2 TL |
119 | ipv4_addr(const socket_address &) noexcept; |
120 | ipv4_addr(const ::in_addr&, uint16_t = 0) noexcept; | |
11fdf7f2 | 121 | |
f67539c2 | 122 | bool is_ip_unspecified() const noexcept { |
9f95a23c | 123 | return ip == 0; |
11fdf7f2 | 124 | } |
f67539c2 | 125 | bool is_port_unspecified() const noexcept { |
9f95a23c TL |
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 | ||
f67539c2 TL |
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 | |
9f95a23c TL |
139 | ipv6_addr(const std::string&); |
140 | ipv6_addr(const std::string&, uint16_t port); | |
f67539c2 TL |
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; | |
9f95a23c | 145 | |
f67539c2 TL |
146 | bool is_ip_unspecified() const noexcept; |
147 | bool is_port_unspecified() const noexcept { | |
9f95a23c TL |
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&); | |
11fdf7f2 | 154 | |
f67539c2 | 155 | inline bool operator==(const ipv4_addr &lhs, const ipv4_addr& rhs) noexcept { |
9f95a23c TL |
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 | } | |
11fdf7f2 TL |
184 | }; |
185 | ||
186 | } |