Commit 27313774 authored by Simon Giesecke's avatar Simon Giesecke

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
parent 314ac28d
...@@ -71,10 +71,6 @@ zmq::tcp_address_t::tcp_address_t (const sockaddr *sa_, socklen_t sa_len_) : ...@@ -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_) ...@@ -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_) ...@@ -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_) ...@@ -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 ...@@ -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_) ...@@ -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_) ...@@ -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_) ...@@ -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_, ...@@ -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_, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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;
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment