12 #ifndef ZMQ_HAVE_WINDOWS
13 #include <sys/types.h>
14 #include <arpa/inet.h>
15 #include <netinet/tcp.h>
38 if (sa_->sa_family == AF_INET
39 && sa_len_ >=
static_cast<socklen_t
> (sizeof (
_address.
ipv4)))
41 else if (sa_->sa_family == AF_INET6
42 && sa_len_ >=
static_cast<socklen_t
> (sizeof (
_address.
ipv6)))
49 const char *src_delimiter = strrchr (
name_,
';');
68 src_resolver.
resolve (&_source_address, src_name.c_str ());
71 name_ = src_delimiter + 1;
88 template <
size_t N1,
size_t N2>
91 const char (&ipv6_prefix_)[N1],
92 const char (&ipv6_suffix_)[N2])
94 const size_t max_port_str_length = 5;
95 char buf[
NI_MAXHOST +
sizeof ipv6_prefix_ +
sizeof ipv6_suffix_
96 + max_port_str_length];
98 memcpy (pos, ipv6_prefix_,
sizeof ipv6_prefix_ - 1);
99 pos +=
sizeof ipv6_prefix_ - 1;
100 const size_t hbuf_len = strlen (hbuf_);
101 memcpy (pos, hbuf_, hbuf_len);
103 memcpy (pos, ipv6_suffix_,
sizeof ipv6_suffix_ - 1);
104 pos +=
sizeof ipv6_suffix_ - 1;
105 int res =
snprintf (pos, max_port_str_length + 1,
"%d", ntohs (port_));
106 zmq_assert (res > 0 && res < (
int) (max_port_str_length + 1));
113 if (_address.family () != AF_INET && _address.family () != AF_INET6) {
121 const int rc = getnameinfo (addr (), addrlen (), hbuf,
sizeof (hbuf),
NULL,
128 const char ipv4_prefix[] =
"tcp://";
129 const char ipv4_suffix[] =
":";
130 const char ipv6_prefix[] =
"tcp://[";
131 const char ipv6_suffix[] =
"]:";
132 if (_address.family () == AF_INET6) {
144 return _address.as_sockaddr ();
149 return _address.sockaddr_len ();
154 return _source_address.as_sockaddr ();
159 return _source_address.sockaddr_len ();
164 return _has_src_addr;
167 #if defined ZMQ_HAVE_WINDOWS
173 return _address.family ();
186 const char *delimiter = strrchr (
name_,
'/');
187 if (delimiter !=
NULL) {
189 mask_str.assign (delimiter + 1);
190 if (mask_str.empty ()) {
195 addr_str.assign (
name_);
208 const int rc = resolver.
resolve (&_network_address, addr_str.c_str ());
213 const int full_mask_ipv4 =
214 sizeof (_network_address.ipv4.sin_addr) * CHAR_BIT;
215 const int full_mask_ipv6 =
216 sizeof (_network_address.ipv6.sin6_addr) * CHAR_BIT;
217 if (mask_str.empty ()) {
218 _address_mask = _network_address.family () == AF_INET6 ? full_mask_ipv6
220 }
else if (mask_str ==
"0")
223 const long mask = strtol (mask_str.c_str (),
NULL, 10);
225 || (_network_address.family () == AF_INET6 &&
mask > full_mask_ipv6)
226 || (_network_address.family () != AF_INET6
227 &&
mask > full_mask_ipv4)) {
231 _address_mask =
static_cast<int> (
mask);
238 const socklen_t ss_len_)
const
242 >=
static_cast<socklen_t
> (
sizeof (
struct sockaddr)));
244 if (ss_->sa_family != _network_address.generic.sa_family)
247 if (_address_mask > 0) {
249 const uint8_t *our_bytes, *their_bytes;
250 if (ss_->sa_family == AF_INET6) {
251 zmq_assert (ss_len_ ==
sizeof (
struct sockaddr_in6));
252 their_bytes =
reinterpret_cast<const uint8_t *
> (
253 &((
reinterpret_cast<const struct sockaddr_in6 *
> (ss_))
255 our_bytes =
reinterpret_cast<const uint8_t *
> (
256 &_network_address.ipv6.sin6_addr);
257 mask =
sizeof (
struct in6_addr) * 8;
259 zmq_assert (ss_len_ ==
sizeof (
struct sockaddr_in));
260 their_bytes =
reinterpret_cast<const uint8_t *
> (&(
261 (
reinterpret_cast<const struct sockaddr_in *
> (ss_))->sin_addr));
262 our_bytes =
reinterpret_cast<const uint8_t *
> (
263 &_network_address.ipv4.sin_addr);
264 mask =
sizeof (
struct in_addr) * 8;
266 if (_address_mask <
mask)
267 mask = _address_mask;
269 const size_t full_bytes =
mask / 8;
270 if (memcmp (our_bytes, their_bytes, full_bytes) != 0)
273 const uint8_t last_byte_bits = 0xffU << (8 -
mask % 8);
274 if (last_byte_bits) {
275 if ((their_bytes[full_bytes] & last_byte_bits)
276 != (our_bytes[full_bytes] & last_byte_bits))