BIND 10 #998: IP based ACL check

BIND 10 Development do-not-reply at isc.org
Wed Jun 22 09:03:03 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      |
-------------------------------------+-------------------------------------

Comment (by jinmei):

 (continued)

 I've completed my review on ip_check.h.  I've not fully reviewed the
 tests yet, but I guess it's better to give the ticket back to Stephen
 at this point.

 == splitIPAddress ==
 - This implementation accepts (e.g.) "/1" or "1/", which should be
   properly rejected with an exception.
 - like createNetmask, should this be public?  Moreover, since this
   isn't templated it will result in duplicate symbols.
 - I'd revise the documentation using the term "prefix" (see the
   general comment), e.g.:
 {{{
 /// Splits an IP prefix (given in the form of "xxxxxx/n" or "xxxxx") into
 a
 /// string representing its address part and the prefix length in bits.
 /// An exception...
 }}}
   "(In the latter case...)" was removed because it's obvious from the
   definition of the prefix length.
 - Likewise, I'd rename the parameter "addrmask" to "ipprefix"
 - Isn't it better to use the max prefix length instead of the magic
   number of -1?  Then we can eliminate the special case consideration
   for negative 'requested' in setNetmask (which I'd call
   setPrefixLength), and we could even make the parameter unsigned int.

 == IPCheck class ==
 - 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.  Especially in a bit more advanced
   languages like C++ we should generally be able to find a better way
   than doing this type of game using union.  Also, the use of uint32_t
   version basically seems to be for performance optimization.  If
   that's the main purpose, it seems to me premature.  We should
   consider optimization after we are sure this is a heavy bottleneck,
   and after we know a specific optimization really improves the
   performance significantly, especially because it uses a dangerous
   hack like tweaking union.  Actually, I'd expect this will eventually
   be a major optimization point considering some operators use very
   large ACLs, but at that point we'll probably need more aggressive
   reconstruction such as introducing a radix/trie, which would make
   this type of micro optimization moot.

 - 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_.  These can be generated on demand from
   other members, and, as commented, these wouldn't be needed in
   performance sensitive path.  On the other hand, we may have a very
   large number of ACL entries, so the contribution of the additional
   redundant member might be significant in terms of memory usage.

 - 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.

 - as we already discussed, I'd suggest removing "inverse".

 - Do we really need the default constructor?  It allows an IPCheck
   oject to have a mostly invalid state, opening up a possibility of
   bugs.

 - constructor from string: inet_pton() could fail with -1, too.

 - constructor from IPvX numeric addresses: I'd pass in_addr&/in6_addr&
   instead of the lower level primitives.

 - copy constructor: couldn't we simply substitute address_ and
   netmask_? i.e., address_ = other.address_, etc.  Same for the
   assignment operator.

 - 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)

 - getFamily: if we don't need to have the default constructor, maybe
   we don't have to worry about the asserts (IMO this is another reason
   why it would be better to not have it if we don't have a meaningful
   way to use it).

 - 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).

 - match(uint32_t): I'd remove this at least for now.  If it's for
   optimization, it seems to me to be premature.  Also, it's not really
   well defined when constructed for an IPv6 prefix.

 - setNetmask: to be very sure, I'd check it doesn't overrun with
   netmask (or we might want to use something like boost::array and use
   at() instead []).

-- 
Ticket URL: <http://bind10.isc.org/ticket/998#comment:18>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list