mirror of
https://github.com/zeromq/libzmq.git
synced 2025-11-10 16:37:45 +01:00
Problem: protected data members in ip_address_t, ip_address_mask_t violates LSP
Solution: make ip_address_mask_t independent of ip_address_t, they do not share that much, remove some code duplication between ip_address_t and ip_addr_t
This commit is contained in:
@@ -71,10 +71,6 @@ zmq::tcp_address_t::tcp_address_t (const sockaddr *sa_, socklen_t sa_len_) :
|
|||||||
memcpy (&_address.ipv6, sa_, sizeof (_address.ipv6));
|
memcpy (&_address.ipv6, sa_, sizeof (_address.ipv6));
|
||||||
}
|
}
|
||||||
|
|
||||||
zmq::tcp_address_t::~tcp_address_t ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv6_)
|
int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv6_)
|
||||||
{
|
{
|
||||||
// Test the ';' to know if we have a source address in name_
|
// Test the ';' to know if we have a source address in name_
|
||||||
@@ -117,7 +113,7 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv6_)
|
|||||||
return resolver.resolve (&_address, name_);
|
return resolver.resolve (&_address, name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::tcp_address_t::to_string (std::string &addr_)
|
int zmq::tcp_address_t::to_string (std::string &addr_) const
|
||||||
{
|
{
|
||||||
if (_address.family () != AF_INET && _address.family () != AF_INET6) {
|
if (_address.family () != AF_INET && _address.family () != AF_INET6) {
|
||||||
addr_.clear ();
|
addr_.clear ();
|
||||||
@@ -127,8 +123,8 @@ int zmq::tcp_address_t::to_string (std::string &addr_)
|
|||||||
// Not using service resolving because of
|
// Not using service resolving because of
|
||||||
// https://github.com/zeromq/libzmq/commit/1824574f9b5a8ce786853320e3ea09fe1f822bc4
|
// https://github.com/zeromq/libzmq/commit/1824574f9b5a8ce786853320e3ea09fe1f822bc4
|
||||||
char hbuf[NI_MAXHOST];
|
char hbuf[NI_MAXHOST];
|
||||||
int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof (hbuf), NULL, 0,
|
const int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof (hbuf), NULL,
|
||||||
NI_NUMERICHOST);
|
0, NI_NUMERICHOST);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
addr_.clear ();
|
addr_.clear ();
|
||||||
return rc;
|
return rc;
|
||||||
@@ -148,28 +144,22 @@ int zmq::tcp_address_t::to_string (std::string &addr_)
|
|||||||
|
|
||||||
const sockaddr *zmq::tcp_address_t::addr () const
|
const sockaddr *zmq::tcp_address_t::addr () const
|
||||||
{
|
{
|
||||||
return &_address.generic;
|
return _address.as_sockaddr ();
|
||||||
}
|
}
|
||||||
|
|
||||||
socklen_t zmq::tcp_address_t::addrlen () const
|
socklen_t zmq::tcp_address_t::addrlen () const
|
||||||
{
|
{
|
||||||
if (_address.generic.sa_family == AF_INET6)
|
return _address.sockaddr_len ();
|
||||||
return static_cast<socklen_t> (sizeof (_address.ipv6));
|
|
||||||
|
|
||||||
return static_cast<socklen_t> (sizeof (_address.ipv4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sockaddr *zmq::tcp_address_t::src_addr () const
|
const sockaddr *zmq::tcp_address_t::src_addr () const
|
||||||
{
|
{
|
||||||
return &_source_address.generic;
|
return _source_address.as_sockaddr ();
|
||||||
}
|
}
|
||||||
|
|
||||||
socklen_t zmq::tcp_address_t::src_addrlen () const
|
socklen_t zmq::tcp_address_t::src_addrlen () const
|
||||||
{
|
{
|
||||||
if (_address.family () == AF_INET6)
|
return _source_address.sockaddr_len ();
|
||||||
return static_cast<socklen_t> (sizeof (_source_address.ipv6));
|
|
||||||
|
|
||||||
return static_cast<socklen_t> (sizeof (_source_address.ipv4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zmq::tcp_address_t::has_src_addr () const
|
bool zmq::tcp_address_t::has_src_addr () const
|
||||||
@@ -186,10 +176,9 @@ sa_family_t zmq::tcp_address_t::family () const
|
|||||||
return _address.family ();
|
return _address.family ();
|
||||||
}
|
}
|
||||||
|
|
||||||
zmq::tcp_address_mask_t::tcp_address_mask_t () :
|
zmq::tcp_address_mask_t::tcp_address_mask_t () : _address_mask (-1)
|
||||||
tcp_address_t (),
|
|
||||||
_address_mask (-1)
|
|
||||||
{
|
{
|
||||||
|
memset (&_network_address, 0, sizeof (_network_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::tcp_address_mask_t::mask () const
|
int zmq::tcp_address_mask_t::mask () const
|
||||||
@@ -224,23 +213,26 @@ int zmq::tcp_address_mask_t::resolve (const char *name_, bool ipv6_)
|
|||||||
|
|
||||||
ip_resolver_t resolver (resolver_opts);
|
ip_resolver_t resolver (resolver_opts);
|
||||||
|
|
||||||
const int rc = resolver.resolve (&_address, addr_str.c_str ());
|
const int rc = resolver.resolve (&_network_address, addr_str.c_str ());
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
// Parse the cidr mask number.
|
// Parse the cidr mask number.
|
||||||
const int full_mask_ipv4 = sizeof (_address.ipv4.sin_addr) * CHAR_BIT;
|
const int full_mask_ipv4 =
|
||||||
const int full_mask_ipv6 = sizeof (_address.ipv6.sin6_addr) * CHAR_BIT;
|
sizeof (_network_address.ipv4.sin_addr) * CHAR_BIT;
|
||||||
|
const int full_mask_ipv6 =
|
||||||
|
sizeof (_network_address.ipv6.sin6_addr) * CHAR_BIT;
|
||||||
if (mask_str.empty ()) {
|
if (mask_str.empty ()) {
|
||||||
_address_mask =
|
_address_mask = _network_address.family () == AF_INET6 ? full_mask_ipv6
|
||||||
_address.family () == AF_INET6 ? full_mask_ipv6 : full_mask_ipv4;
|
: full_mask_ipv4;
|
||||||
} else if (mask_str == "0")
|
} else if (mask_str == "0")
|
||||||
_address_mask = 0;
|
_address_mask = 0;
|
||||||
else {
|
else {
|
||||||
const int mask = atoi (mask_str.c_str ());
|
const int mask = atoi (mask_str.c_str ());
|
||||||
if ((mask < 1)
|
if ((mask < 1)
|
||||||
|| (_address.family () == AF_INET6 && mask > full_mask_ipv6)
|
|| (_network_address.family () == AF_INET6 && mask > full_mask_ipv6)
|
||||||
|| (_address.family () != AF_INET6 && mask > full_mask_ipv4)) {
|
|| (_network_address.family () != AF_INET6
|
||||||
|
&& mask > full_mask_ipv4)) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -250,9 +242,10 @@ int zmq::tcp_address_mask_t::resolve (const char *name_, bool ipv6_)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::tcp_address_mask_t::to_string (std::string &addr_)
|
int zmq::tcp_address_mask_t::to_string (std::string &addr_) const
|
||||||
{
|
{
|
||||||
if (_address.family () != AF_INET && _address.family () != AF_INET6) {
|
if (_network_address.family () != AF_INET
|
||||||
|
&& _network_address.family () != AF_INET6) {
|
||||||
addr_.clear ();
|
addr_.clear ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -262,14 +255,15 @@ int zmq::tcp_address_mask_t::to_string (std::string &addr_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char hbuf[NI_MAXHOST];
|
char hbuf[NI_MAXHOST];
|
||||||
int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof (hbuf), NULL, 0,
|
const int rc = getnameinfo (_network_address.as_sockaddr (),
|
||||||
NI_NUMERICHOST);
|
_network_address.sockaddr_len (), hbuf,
|
||||||
|
sizeof (hbuf), NULL, 0, NI_NUMERICHOST);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
addr_.clear ();
|
addr_.clear ();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_address.family () == AF_INET6) {
|
if (_network_address.family () == AF_INET6) {
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "[" << hbuf << "]/" << _address_mask;
|
s << "[" << hbuf << "]/" << _address_mask;
|
||||||
addr_ = s.str ();
|
addr_ = s.str ();
|
||||||
@@ -285,9 +279,10 @@ bool zmq::tcp_address_mask_t::match_address (const struct sockaddr *ss_,
|
|||||||
const socklen_t ss_len_) const
|
const socklen_t ss_len_) const
|
||||||
{
|
{
|
||||||
zmq_assert (_address_mask != -1 && ss_ != NULL
|
zmq_assert (_address_mask != -1 && ss_ != NULL
|
||||||
&& ss_len_ >= (socklen_t) sizeof (struct sockaddr));
|
&& ss_len_
|
||||||
|
>= static_cast<socklen_t> (sizeof (struct sockaddr)));
|
||||||
|
|
||||||
if (ss_->sa_family != _address.generic.sa_family)
|
if (ss_->sa_family != _network_address.generic.sa_family)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (_address_mask > 0) {
|
if (_address_mask > 0) {
|
||||||
@@ -298,15 +293,15 @@ bool zmq::tcp_address_mask_t::match_address (const struct sockaddr *ss_,
|
|||||||
their_bytes = reinterpret_cast<const uint8_t *> (
|
their_bytes = reinterpret_cast<const uint8_t *> (
|
||||||
&((reinterpret_cast<const struct sockaddr_in6 *> (ss_))
|
&((reinterpret_cast<const struct sockaddr_in6 *> (ss_))
|
||||||
->sin6_addr));
|
->sin6_addr));
|
||||||
our_bytes =
|
our_bytes = reinterpret_cast<const uint8_t *> (
|
||||||
reinterpret_cast<const uint8_t *> (&_address.ipv6.sin6_addr);
|
&_network_address.ipv6.sin6_addr);
|
||||||
mask = sizeof (struct in6_addr) * 8;
|
mask = sizeof (struct in6_addr) * 8;
|
||||||
} else {
|
} else {
|
||||||
zmq_assert (ss_len_ == sizeof (struct sockaddr_in));
|
zmq_assert (ss_len_ == sizeof (struct sockaddr_in));
|
||||||
their_bytes = reinterpret_cast<const uint8_t *> (&(
|
their_bytes = reinterpret_cast<const uint8_t *> (&(
|
||||||
(reinterpret_cast<const struct sockaddr_in *> (ss_))->sin_addr));
|
(reinterpret_cast<const struct sockaddr_in *> (ss_))->sin_addr));
|
||||||
our_bytes =
|
our_bytes = reinterpret_cast<const uint8_t *> (
|
||||||
reinterpret_cast<const uint8_t *> (&_address.ipv4.sin_addr);
|
&_network_address.ipv4.sin_addr);
|
||||||
mask = sizeof (struct in_addr) * 8;
|
mask = sizeof (struct in_addr) * 8;
|
||||||
}
|
}
|
||||||
if (_address_mask < mask)
|
if (_address_mask < mask)
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class tcp_address_t
|
|||||||
public:
|
public:
|
||||||
tcp_address_t ();
|
tcp_address_t ();
|
||||||
tcp_address_t (const sockaddr *sa_, socklen_t sa_len_);
|
tcp_address_t (const sockaddr *sa_, socklen_t sa_len_);
|
||||||
virtual ~tcp_address_t ();
|
|
||||||
|
|
||||||
// This function translates textual TCP address into an address
|
// This function translates textual TCP address into an address
|
||||||
// structure. If 'local' is true, names are resolved as local interface
|
// structure. If 'local' is true, names are resolved as local interface
|
||||||
@@ -53,7 +52,7 @@ class tcp_address_t
|
|||||||
int resolve (const char *name_, bool local_, bool ipv6_);
|
int resolve (const char *name_, bool local_, bool ipv6_);
|
||||||
|
|
||||||
// The opposite to resolve()
|
// The opposite to resolve()
|
||||||
virtual int to_string (std::string &addr_);
|
int to_string (std::string &addr_) const;
|
||||||
|
|
||||||
#if defined ZMQ_HAVE_WINDOWS
|
#if defined ZMQ_HAVE_WINDOWS
|
||||||
unsigned short family () const;
|
unsigned short family () const;
|
||||||
@@ -67,13 +66,13 @@ class tcp_address_t
|
|||||||
socklen_t src_addrlen () const;
|
socklen_t src_addrlen () const;
|
||||||
bool has_src_addr () const;
|
bool has_src_addr () const;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
ip_addr_t _address;
|
ip_addr_t _address;
|
||||||
ip_addr_t _source_address;
|
ip_addr_t _source_address;
|
||||||
bool _has_src_addr;
|
bool _has_src_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class tcp_address_mask_t : public tcp_address_t
|
class tcp_address_mask_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
tcp_address_mask_t ();
|
tcp_address_mask_t ();
|
||||||
@@ -84,7 +83,7 @@ class tcp_address_mask_t : public tcp_address_t
|
|||||||
int resolve (const char *name_, bool ipv6_);
|
int resolve (const char *name_, bool ipv6_);
|
||||||
|
|
||||||
// The opposite to resolve()
|
// The opposite to resolve()
|
||||||
int to_string (std::string &addr_);
|
int to_string (std::string &addr_) const;
|
||||||
|
|
||||||
int mask () const;
|
int mask () const;
|
||||||
|
|
||||||
@@ -92,6 +91,7 @@ class tcp_address_mask_t : public tcp_address_t
|
|||||||
const socklen_t ss_len_) const;
|
const socklen_t ss_len_) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ip_addr_t _network_address;
|
||||||
int _address_mask;
|
int _address_mask;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user