LCOV - code coverage report
Current view: top level - nsas - nameserver_entry.h (source / functions) Hit Total Coverage
Test: report.info Lines: 15 21 71.4 %
Date: 2012-05-15 Functions: 4 13 30.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 20 58 34.5 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #ifndef __NAMESERVER_ENTRY_H
      16                 :            : #define __NAMESERVER_ENTRY_H
      17                 :            : 
      18                 :            : #include <string>
      19                 :            : #include <vector>
      20                 :            : #include <boost/enable_shared_from_this.hpp>
      21                 :            : 
      22                 :            : #include <exceptions/exceptions.h>
      23                 :            : #include <dns/rrset.h>
      24                 :            : #include <dns/rrtype.h>
      25                 :            : 
      26                 :            : #include <resolve/resolver_interface.h>
      27                 :            : 
      28                 :            : #include <util/lru_list.h>
      29                 :            : 
      30                 :            : #include "address_entry.h"
      31                 :            : #include "asiolink.h"
      32                 :            : #include "nsas_types.h"
      33                 :            : #include "hash_key.h"
      34                 :            : #include "fetchable.h"
      35                 :            : #include "nsas_entry.h"
      36                 :            : #include "nameserver_address.h"
      37                 :            : 
      38                 :            : namespace isc {
      39                 :            : namespace nsas {
      40                 :            : 
      41                 :            : class NameserverAddress;
      42                 :            : 
      43                 :            : /// \brief Inconsistent Owner Names
      44                 :            : ///
      45                 :            : /// Thrown if a NameserverEntry is constructed from both an A and AAAA RRset
      46                 :            : /// where the owner names do not match.
      47                 :          0 : class InconsistentOwnerNames : public Exception {
      48                 :            : public:
      49                 :            :     InconsistentOwnerNames(const char* file, size_t line, const char* what) :
      50                 :            :         isc::Exception(file, line, what)
      51                 :            :     {}
      52                 :            : };
      53                 :            : 
      54                 :            : /// \brief RTT is zero
      55                 :            : ///
      56                 :            : /// Thrown if a RTT related with an address is 0.
      57                 :          0 : class RTTIsZero : public Exception {
      58                 :            : public:
      59                 :            :     RTTIsZero(const char* file, size_t line, const char* what) :
      60         [ #  # ]:          0 :         isc::Exception(file, line, what)
      61                 :            :     {}
      62                 :            : };
      63                 :            : 
      64                 :            : /// \brief Inconsistent Class
      65                 :            : ///
      66                 :            : /// Thrown if a NameserverEntry is constructed from both an A and AAAA RRset
      67                 :            : /// where the classes do not match.
      68                 :          0 : class InconsistentClass : public Exception {
      69                 :            : public:
      70                 :            :     InconsistentClass(const char* file, size_t line, const char* what) :
      71                 :            :         isc::Exception(file, line, what)
      72                 :            :     {}
      73                 :            : };
      74                 :            : 
      75                 :            : class ZoneEntry;
      76                 :            : 
      77                 :            : /// \brief Nameserver Entry
      78                 :            : ///
      79                 :            : /// Describes a nameserver and its addresses.  A nameserver be authoritative
      80                 :            : /// for several zones (hence is pointed to by more than one zone entry), and
      81                 :            : /// may have several addresses associated with it.
      82                 :            : ///
      83                 :            : /// The addresses expire after their TTL has been reached.  For simplicity,
      84                 :            : /// (and because it is unlikely that A and AAAA records from the same zone have
      85                 :            : /// different TTLs) there is one expiration time for all address records.
      86                 :            : /// When that is reached, all records are declared expired and new fetches
      87                 :            : /// started for the information.
      88                 :            : ///
      89                 :            : /// As this object will be stored in the nameserver address store LRU list,
      90                 :            : /// it is derived from the LRU list entry class.
      91                 :            : ///
      92                 :            : /// It uses shared_from_this in its methods. It must live inside a shared_ptr.
      93                 :            : 
      94 [ +  - ][ +  + ]:        774 : class NameserverEntry : public NsasEntry<NameserverEntry>, public Fetchable {
         [ +  - ][ +  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      95                 :            : public:
      96                 :            :     /// List of addresses associated with this nameserver
      97                 :            :     typedef std::vector<NameserverAddress>   AddressVector;
      98                 :            :     typedef AddressVector::iterator     AddressVectorIterator;
      99                 :            : 
     100                 :            :     /// \brief Constructor where no A records are supplied.
     101                 :            :     ///
     102                 :            :     /// \param name Name of the nameserver,
     103                 :            :     /// \param class_code class of the nameserver
     104                 :         21 :     NameserverEntry(const std::string& name,
     105                 :            :         const isc::dns::RRClass& class_code) :
     106                 :            :         name_(name),
     107                 :            :         classCode_(class_code),
     108 [ +  - ][ +  + ]:        560 :         expiration_(0)
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
     109                 :            :     {
     110                 :        112 :         has_address_[V4_ONLY] = false;
     111                 :        112 :         has_address_[V6_ONLY] = false;
     112                 :        112 :         has_address_[ANY_OK] = false;
     113                 :        112 :         expect_address_[V4_ONLY] = false;
     114                 :        112 :         expect_address_[V6_ONLY] = false;
     115                 :        112 :         expect_address_[ANY_OK] = false;
     116                 :         21 :     }
     117                 :            : 
     118                 :            :     /*
     119                 :            :      * \brief Return Address
     120                 :            :      *
     121                 :            :      * Returns a vector of addresses corresponding to this nameserver.
     122                 :            :      *
     123                 :            :      * \param addresses Vector of address entries into which will be appended
     124                 :            :      *     addresses that match the specified criteria. (The reason for
     125                 :            :      *     choosing this signature is that addresses from more than one
     126                 :            :      *     nameserver may be retrieved, in which case appending to an existing
     127                 :            :      *     list of addresses is convenient.)
     128                 :            :      * \param family The family of address that is requested.
     129                 :            :      * \param expired_ok Return addresses even when expired. This is here
     130                 :            :      *     because an address with TTL 0 is expired at the exact time it
     131                 :            :      *     arrives. But when we call the callback, the owner of callback
     132                 :            :      *     is allowed to use them anyway so it should set expired_ok
     133                 :            :      *     to true.
     134                 :            :      * \return The state this is currently in. If the TTL expires, it enters
     135                 :            :      *     the EXPIRED state by itself and passes no addresses. It may be
     136                 :            :      *     IN_PROGRESS and still return some addresses (when one address family
     137                 :            :      *     arrived and is is returned, but the other is still on the way).
     138                 :            :      * \todo Should we sort out unreachable addresses as well?
     139                 :            :      */
     140                 :            :     Fetchable::State getAddresses(AddressVector& addresses,
     141                 :            :         AddressFamily family = ANY_OK, bool expired_ok = false);
     142                 :            : 
     143                 :            :     /// \brief Return Address that corresponding to the index
     144                 :            :     ///
     145                 :            :     /// \param index The address index in the address vector
     146                 :            :     /// \param family The address family, V4_ONLY or V6_ONLY
     147                 :            :     asiolink::IOAddress getAddressAtIndex(size_t index,
     148                 :            :         AddressFamily family) const;
     149                 :            : 
     150                 :            :     /// \brief Update RTT
     151                 :            :     ///
     152                 :            :     /// Updates the RTT for a particular address
     153                 :            :     ///
     154                 :            :     /// \param address Address to update
     155                 :            :     /// \param rtt New RTT for the address
     156                 :            :     void setAddressRTT(const asiolink::IOAddress& address, uint32_t rtt);
     157                 :            : 
     158                 :            :     /// \brief Update RTT of the address that corresponding to the index
     159                 :            :     ///
     160                 :            :     /// Shouldn't probably be used directly. Use corresponding
     161                 :            :     /// NameserverAddress.
     162                 :            :     /// \param rtt Round-Trip Time
     163                 :            :     /// \param index The address's index in address vector
     164                 :            :     /// \param family The address family, V4_ONLY or V6_ONLY
     165                 :            :     void updateAddressRTTAtIndex(uint32_t rtt, size_t index,
     166                 :            :         AddressFamily family);
     167                 :            :     /**
     168                 :            :      * \short Update RTT of an address.
     169                 :            :      *
     170                 :            :      * This is similar to updateAddressRTTAtIndex, but you pass the address,
     171                 :            :      * not it's index. Passing the index might be unsafe, because the position
     172                 :            :      * of the address or the cound of addresses may change in time.
     173                 :            :      *
     174                 :            :      * \param rtt Round-Trip Time
     175                 :            :      * \param address The address whose RTT should be updated.
     176                 :            :      * \param family The address family, V4_ONLY or V6_ONLY
     177                 :            :      */
     178                 :            :     void updateAddressRTT(uint32_t rtt, const asiolink::IOAddress& address,
     179                 :            :         AddressFamily family);
     180                 :            : 
     181                 :            :     /// \brief Set Address Unreachable
     182                 :            :     ///
     183                 :            :     /// Sets the specified address to be unreachable
     184                 :            :     ///
     185                 :            :     /// \param address Address to update
     186                 :            :     void setAddressUnreachable(const asiolink::IOAddress& address);
     187                 :            : 
     188                 :            :     /// \return Owner Name of RRset
     189                 :            :     std::string getName() const {
     190   [ +  -  +  -  :        328 :         return name_;
             +  -  #  # ]
           [ #  #  +  - ]
     191                 :            :     }
     192                 :            : 
     193                 :            :     /// \return Class of RRset
     194                 :            :     const isc::dns::RRClass& getClass() const {
     195                 :            :         return classCode_;
     196                 :            :     }
     197                 :            : 
     198                 :            :     /// \return Hash Key of the Nameserver
     199                 :         52 :     virtual HashKey hashKey() const {
     200                 :         52 :         return HashKey(name_, classCode_);
     201                 :            :     }
     202                 :            : 
     203                 :            :     /// \return Hash Key of the Nameserver
     204                 :            : 
     205                 :            :     /// \return Expiration Time of Data
     206                 :            :     ///
     207                 :            :     /// Returns the expiration time of addresses for this nameserver.  For
     208                 :            :     /// simplicity, this quantity is calculated as the minimum expiration time
     209                 :            :     /// of the A and AAAA address records.
     210                 :          0 :     time_t getExpiration() const {
     211                 :          0 :         return expiration_;
     212                 :            :     }
     213                 :            : 
     214                 :            :     /// \name Obtaining the IP addresses from resolver
     215                 :            :     //@{
     216                 :            :     /// \short A callback that some information here arrived (or are unavailable).
     217                 :         94 :     struct Callback {
     218                 :            :         virtual void operator()(boost::shared_ptr<NameserverEntry> self) = 0;
     219                 :            :         /// \short Virtual destructor, so descendants are properly cleaned up
     220                 :         94 :         virtual ~ Callback() {}
     221                 :            :     };
     222                 :            : 
     223                 :            :     /**
     224                 :            :      * \short Asks the resolver for IP address (or addresses).
     225                 :            :      *
     226                 :            :      * Adds a callback for given zone when they are ready or the information
     227                 :            :      * is found unreachable.
     228                 :            :      *
     229                 :            :      * If it is not in NOT_ASKED or EXPIRED state, it does not ask the for the
     230                 :            :      * IP address again, it just inserts the callback. It is up to the caller
     231                 :            :      * not to insert one callback multiple times.
     232                 :            :      *
     233                 :            :      * The callback might be called directly from this function.
     234                 :            :      *
     235                 :            :      * \param resolver Who to ask.
     236                 :            :      * \param callback The callback.
     237                 :            :      * \param family Which addresses are interesting to the caller. This does
     238                 :            :      *     not change which adresses are requested, but the callback might
     239                 :            :      *     be executed when at last one requested type is available (eg. not
     240                 :            :      *     waiting for the other one).
     241                 :            :      * \return The state the entry is currently in. It can return UNREACHABLE
     242                 :            :      *     even when there are addresses, if there are no addresses for this
     243                 :            :      *     family.
     244                 :            :      */
     245                 :            :     void askIP(isc::resolve::ResolverInterface* resolver,
     246                 :            :         boost::shared_ptr<Callback> callback, AddressFamily family);
     247                 :            :     //@}
     248                 :            : 
     249                 :            : private:
     250                 :            :     mutable isc::util::locks::recursive_mutex    mutex_;///< Mutex protecting this object
     251                 :            :     std::string     name_;              ///< Canonical name of the nameserver
     252                 :            :     isc::dns::RRClass classCode_;       ///< Class of the nameserver
     253                 :            :     /**
     254                 :            :      * \short Address lists.
     255                 :            :      *
     256                 :            :      * Only V4_ONLY and V6_ONLY is used, therefore we use the nearest larger
     257                 :            :      * value as the size of the array.
     258                 :            :      *
     259                 :            :      * previous_addresses is kept until the data arrive again on re-fetch and
     260                 :            :      * is used to pick up the RTTs from there.
     261                 :            :      */
     262                 :            :     std::vector<AddressEntry> addresses_[ANY_OK], previous_addresses_[ANY_OK];
     263                 :            :     time_t          expiration_;        ///< Summary expiration time. 0 = unset
     264                 :            :     // Do we have some addresses already? Do we expect some to come?
     265                 :            :     // These are set after asking for IP, if NOT_ASKED, they are uninitialized
     266                 :            :     bool has_address_[ADDR_REQ_MAX], expect_address_[ADDR_REQ_MAX];
     267                 :            :     // Callbacks from resolver
     268                 :            :     class ResolverCallback;
     269                 :            :     friend class ResolverCallback;
     270                 :            :     // Callbacks inserted into this object
     271                 :            :     typedef std::pair<AddressFamily, boost::shared_ptr<Callback> >
     272                 :            :         CallbackPair;
     273                 :            :     std::vector<CallbackPair> callbacks_;
     274                 :            :     /// \short Private version that does the actual asking of one address type
     275                 :            :     ///
     276                 :            :     /// Call unlocked.
     277                 :            :     void askIP(isc::resolve::ResolverInterface* resolver,
     278                 :            :         const isc::dns::RRType&, AddressFamily);
     279                 :            : };
     280                 :            : 
     281                 :            : }   // namespace dns
     282                 :            : }   // namespace isc
     283                 :            : 
     284                 :            : #endif // __NAMESERVER_ENTRY_H

Generated by: LCOV version 1.9