BIND 10 #998: IP based ACL check
BIND 10 Development
do-not-reply at isc.org
Wed Jun 22 20:55:51 UTC 2011
#998: IP based ACL check
-------------------------------------+-------------------------------------
Reporter: | Owner: jinmei
vorner | Status: reviewing
Type: task | Milestone:
Priority: major | Sprint-20110628
Component: | Resolution:
Unclassified | Sensitive: 0
Keywords: | Sub-Project: DNS
Defect Severity: N/A | Estimated Difficulty: 5.0
Feature Depending on Ticket: | Total Hours: 0
Add Hours to Ticket: 0 |
Internal?: 0 |
-------------------------------------+-------------------------------------
Changes (by stephen):
* owner: stephen => jinmei
Comment:
> Maybe a matter of preference, but I'd use the term "prefix" instead of
(address+)netmask unless we want to support non contiguous network masks.
Done.
> maybe we want to have a keyword "any" (or perhaps "any4"/"any6")
Good point. I missed the "match any address from this family". The
string constructor now accepts "any4" and "any6".
> on a related note, I guess we'd probably want to use 0-length prefix to
indicate an "any" match.
Done.
> createNetmask: should this be public? ...
Renamed to "createMask" (to get rid of the "netmask" connotation) and
placed in the "internal" namespace (which seemed more to convey the idea
that this is an internal function than "detail" would).
> I suspect this should be "w-m < w" (at least the current expression
doesn't make sense to me):
It was a typo - fixed.
> For exception, I'd use \exception markup (that would also be helpful for
my work-in-progress...
Done.
> splitIPAddress: This implementation accepts (e.g.) "/1" or "1/", which
should be properly rejected with an exception.
Sigh. That's what you get when you try to use something that does not
*exactly* do the thing you're after. The method now does its own parsing
and this should be fixed.
> like createNetmask, should this be public? Moreover, since this isn't
templated it will result in duplicate symbols.
Well-noticed. Moved to ip_check.cc
> I'd revise the documentation using the term "prefix" (see the general
comment), e.g.:
Done.
> Likewise, I'd rename the parameter "addrmask" to "ipprefix"
Done.
> Isn't it better to use the max prefix length instead of the magic number
of -1?
No. At the point where that is returned, all that is known is that the
string passed (presumably) comprises an address and no prefix length. At
that point, the maximum valid prefix length is not yet known. As a value
of 0 is now being interpreted as a request to match any address of this
family, -1 is the easiest way of passing back information about the
absence of a prefix length. (Note that explicitly specifying a negative
number as the prefix length will cause an exception to be thrown, so the
only way -1 can be returned is if no prefix length is given.)
> setNetmask (which I'd call setPrefixLength...
I've renamed it to setMask - as it's creating a mask used in a logical
operation, this seems appropriate.
> The union usage for !AddressData seems dangerous in that it breaks the
basic rule of union: don't read a member that's different from a member
that was last written.
I've not come across that before - I guess that this allows compiler some
optimisation and we may fall foul of that and you
would need to use a "volatile" keyword to avoid it. OK, rewritten using a
vector<uint8_t>.
> at the risk of sounding self contradicting, I'd be a bit concerned about
the redundant member variables like masksize_ (which I'd call prefixlen_)
and straddr_.
Removed. A toText() method can be added if we need it, and getPrefixlen()
now calculates the prefix length on the fly.
> Likewise, I wonder whether we might want to allocate spaces for address
and mask dynamically, and only for the necessary amount depending on the
address family.
vector<uint8_t> is now used.
> as we already discussed, I'd suggest removing "inverse".
Done.
> Do we really need the default constructor? It allows an IPCheck object
to have a mostly invalid state, opening up a possibility of bugs.
Depends if it is needed. I added the default constructor to facilitate
its use in vectors and the like (e.g. initializing a vector of IPCheck
objects to a known size), but it's trivial to remove it. (Note that
compare() for an acl constructed with the default constructor will always
return false for both IPV4 and IPV6 addresses).
> constructor from string: inet_pton() could fail with -1, too.
This is only with an invalid address family, but the code now checks for
the explicit success status.
> constructor from IPvX numeric addresses: I'd pass in_addr&/in6_addr&
instead of the lower level primitives.
Unless we really need them, let's leave it for now. Its just too much
effort to modify the tests.
> copy constructor: couldn't we simply substitute address_ and netmask_?
i.e., address_ = other.address_, etc. Same for the assignment operator.
Yes you can. I'm confusing it with assignment, where array copies are not
allowed. However, I've removed the copy constructor and assignment
operator as they're now not needed.
> getNetmask(): I'd instead define a method returning a prefix length
(int) because conceptually this class works with prefix lengths; netmasks
are just internal representation (probably for faster matching)
getPrefixlen() has been provided. getNetmask() (now renamed getMask()) is
retained as it allows inspection of the internal mask, which is helpful in
testing.
> getFamily: if we don't need to have the default constructor, maybe we
don't have to worry about the asserts
If we remove the default constructor, we'll remove the asserts. They're
static asserts, so have no run-time impact.
> match(const uint8_t*): I'd like this method to support multiple families
of addresses (and simply return false if address families don't match)
either by having an additional "family" parameter or by taking an
IPAddress structure as I defined in trac999preview branch (which is now in
the central repo for reference). Otherwise, each specialization of
matches() needs to deal with the address family mismatches (as I did in
trac999review).
Added a "family" argument.
> match(uint32_t): I'd remove this at least for now.
Removed.
> setNetmask: to be very sure, I'd check it doesn't overrun with netmask
Modified to ensure this.
One final thing. At present the address and comparison bitmask are both
equal to the size of addresses of the relevant family. A possibly
premature optimization would be to truncate them to the size dictated by
the prefix length (e.g. is the prefix length were specified as /8, just
store one byte). However, this will take a little time to do and you did
suggest that you are waiting on these changes.
--
Ticket URL: <http://bind10.isc.org/ticket/998#comment:21>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list