zone.h 27.8 KB
 Michal Vaner committed Dec 21, 2010 1 ``````// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") `````` Michal Vaner committed Dec 21, 2010 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ``````// // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. #ifndef __ZONE_H #define __ZONE_H 1 `````` JINMEI Tatuya committed Aug 16, 2011 18 ``````#include `````` chenzhengzhang committed Jan 25, 2011 19 ``````#include `````` Michal Vaner committed Dec 21, 2010 20 `````` `````` JINMEI Tatuya committed Aug 16, 2011 21 22 ``````#include `````` Michal Vaner committed Dec 21, 2010 23 24 25 ``````namespace isc { namespace datasrc { `````` JINMEI Tatuya committed Sep 08, 2011 26 ``````/// \brief The base class to search a zone for RRsets `````` Michal Vaner committed Dec 21, 2010 27 ``````/// `````` JINMEI Tatuya committed Sep 08, 2011 28 29 30 31 32 33 34 35 ``````/// The \c ZoneFinder class is an abstract base class for representing /// an object that performs DNS lookups in a specific zone accessible via /// a data source. In general, different types of data sources (in-memory, /// database-based, etc) define their own derived classes of \c ZoneFinder, /// implementing ways to retrieve the required data through the common /// interfaces declared in the base class. Each concrete \c ZoneFinder /// object is therefore (conceptually) associated with a specific zone /// of one specific data source instance. `````` Michal Vaner committed Dec 21, 2010 36 ``````/// `````` JINMEI Tatuya committed Sep 08, 2011 37 38 ``````/// The origin name and the RR class of the associated zone are available /// via the \c getOrigin() and \c getClass() methods, respectively. `````` Michal Vaner committed Dec 21, 2010 39 ``````/// `````` JINMEI Tatuya committed Sep 08, 2011 40 41 42 ``````/// The most important method of this class is \c find(), which performs /// the lookup for a given domain and type. See the description of the /// method for details. `````` Michal Vaner committed Dec 21, 2010 43 ``````/// `````` JINMEI Tatuya committed Sep 08, 2011 44 45 46 47 48 49 50 ``````/// \note It's not clear whether we should request that a zone finder form a /// "transaction", that is, whether to ensure the finder is not susceptible /// to changes made by someone else than the creator of the finder. If we /// don't request that, for example, two different lookup results for the /// same name and type can be different if other threads or programs make /// updates to the zone between the lookups. We should revisit this point /// as we gain more experiences. `````` JINMEI Tatuya committed Jul 22, 2011 51 ``````class ZoneFinder { `````` Michal Vaner committed Dec 21, 2010 52 53 54 55 56 ``````public: /// Result codes of the \c find() method. /// /// Note: the codes are tentative. We may need more, or we may find /// some of them unnecessary as we implement more details. `````` Michal 'vorner' Vaner committed Sep 09, 2011 57 58 59 60 61 62 63 64 `````` /// /// Some are synonyms of others in terms of RCODE returned to user. /// But they help the logic to decide if it should ask for a NSEC /// that covers something or not (for example, in case of NXRRSET, /// the directly returned NSEC is sufficient, but with wildcard one, /// we need to add one proving there's no exact match and this is /// actually the best wildcard we have). Data sources that don't /// support DNSSEC don't need to distinguish them. `````` Michal 'vorner' Vaner committed Sep 26, 2011 65 `````` /// `````` JINMEI Tatuya committed Oct 14, 2011 66 67 68 69 `````` /// In case of CNAME, if the CNAME is a wildcard (i.e., its owner name /// starts with the label "*"), WILDCARD_CNAME will be returned instead /// of CNAME. /// `````` JINMEI Tatuya committed Oct 14, 2011 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 `````` /// In case of NXDOMAIN, the returned NSEC covers the queried domain /// that proves that the query name does not exist in the zone. Note that /// this does not necessarily prove it doesn't even match a wildcard /// (even if the result of NXDOMAIN can only happen when there's no /// matching wildcard either). It is caller's responsibility to provide /// a proof that there is no matching wildcard if that proof is necessary. /// /// Various variants of "no data" cases are complicated, when involves /// DNSSEC and wildcard processing. Referring to Section 3.1.3 of /// RFC4035, we need to consider the following cases: /// -# (Normal) no data: there is a matching non-wildcard name with a /// different RR type. This is the "No Data" case of the RFC. /// -# (Normal) empty non terminal: there is no matching (exact or /// wildcard) name, but there is a subdomain with an RR of the query /// name. This is one case of "Name Error" of the RFC. /// -# Wildcard empty non terminal: similar to 2a, but the empty name /// is a wildcard, and matches the query name by wildcard expansion. /// This is a special case of "Name Error" of the RFC. /// -# Wildcard no data: there is no exact match name, but there is a /// wildcard name that matches the query name with a different type /// of RR. This is the "Wildcard No Data" case of the RFC. /// /// In any case, \c find() will result in \c NXRRSET with no RRset /// unless the \c FIND_DNSSEC option is specified. The rest of the /// discussion only applies to the case where this option is specified. /// /// In case 1, \c find() will result in NXRRSET, and return NSEC of the /// matching name. /// /// In case 2, \c find() will result in NXRRSET, and return NSEC for the /// interval where the empty nonterminal lives. The end of the interval /// is the subdomain causing existence of the empty nonterminal (if /// there's sub.x.example.com, and no record in x.example.com, then /// x.example.com exists implicitly - is the empty nonterminal and /// sub.x.example.com is the subdomain causing it). Note that this NSEC /// proves not only the existence of empty non terminal name but also /// the non existence of possibly matching wildcard name, because /// there can be no better wildcard match than the exact matching empty /// name. /// /// In case 3, \c find() will result in WILDCARD_NXRRSET, and return NSEC /// for the interval where the wildcard empty nonterminal lives. /// Cases 2 and 3 are especially complicated and confusing. See the /// examples below. /// /// In case 4, \c find() will result in WILDCARD_NXRRSET, and return /// NSEC of the matching wildcard name. `````` Michal 'vorner' Vaner committed Sep 27, 2011 117 `````` /// `````` JINMEI Tatuya committed Sep 27, 2011 118 `````` /// Examples: if zone "example.com" has the following record: `````` JINMEI Tatuya committed Sep 27, 2011 119 `````` /// \code `````` JINMEI Tatuya committed Oct 14, 2011 120 `````` /// a.example.com. NSEC a.b.example.com. `````` JINMEI Tatuya committed Sep 27, 2011 121 `````` /// \endcode `````` JINMEI Tatuya committed Oct 14, 2011 122 123 `````` /// a call to \c find() for "b.example.com." with the FIND_DNSSEC option /// will result in NXRRSET, and this NSEC will be returned. `````` JINMEI Tatuya committed Sep 27, 2011 124 125 `````` /// Likewise, if zone "example.org" has the following record, /// \code `````` JINMEI Tatuya committed Oct 14, 2011 126 `````` /// a.example.org. NSEC x.*.b.example.org. `````` JINMEI Tatuya committed Sep 27, 2011 127 `````` /// \endcode `````` JINMEI Tatuya committed Oct 14, 2011 128 129 `````` /// a call to \c find() for "y.b.example.org" with FIND_DNSSEC will /// result in NXRRSET_NXRRSET, and this NSEC will be returned. `````` Michal Vaner committed Dec 21, 2010 130 131 132 133 134 135 `````` enum Result { SUCCESS, ///< An exact match is found. DELEGATION, ///< The search encounters a zone cut. NXDOMAIN, ///< There is no domain name that matches the search name NXRRSET, ///< There is a matching name but no RRset of the search type CNAME, ///< The search encounters and returns a CNAME RR `````` Michal 'vorner' Vaner committed Sep 09, 2011 136 137 `````` DNAME, ///< The search encounters and returns a DNAME RR WILDCARD, ///< Succes by wildcard match, for DNSSEC `````` JINMEI Tatuya committed Oct 14, 2011 138 `````` WILDCARD_CNAME, ///< CNAME on wildcard, search returns CNAME, for DNSSEC `````` Michal 'vorner' Vaner committed Sep 09, 2011 139 `````` WILDCARD_NXRRSET ///< NXRRSET on wildcard, for DNSSEC `````` Michal Vaner committed Dec 21, 2010 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 `````` }; /// A helper structure to represent the search result of \c find(). /// /// This is a straightforward tuple of the result code and a pointer /// to the found RRset to represent the result of \c find() /// (there will be more members in the future - see the class /// description). /// We use this in order to avoid overloading the return value for both /// the result code ("success" or "not found") and the found object, /// i.e., avoid using \c NULL to mean "not found", etc. /// /// This is a simple value class whose internal state never changes, /// so for convenience we allow the applications to refer to the members /// directly. /// /// Note: we should eventually include a notion of "zone node", which /// corresponds to a particular domain name of the zone, so that we can /// find RRsets of a different RR type for that name (e.g. for type ANY /// query or to include DS RRs with delegation). /// /// Note: we may also want to include the closest enclosure "node" to /// optimize including the NSEC for no-wildcard proof (FWIW NSD does that). struct FindResult { FindResult(Result param_code, const isc::dns::ConstRRsetPtr param_rrset) : code(param_code), rrset(param_rrset) {} const Result code; const isc::dns::ConstRRsetPtr rrset; }; `````` JINMEI Tatuya committed Dec 30, 2010 172 173 174 175 176 177 178 `````` /// Find options. /// /// The option values are used as a parameter for \c find(). /// These are values of a bitmask type. Bitwise operations can be /// performed on these values to express compound options. enum FindOptions { FIND_DEFAULT = 0, ///< The default options `````` Michal 'vorner' Vaner committed Aug 25, 2011 179 `````` FIND_GLUE_OK = 1, ///< Allow search under a zone cut `````` JINMEI Tatuya committed Oct 14, 2011 180 `````` FIND_DNSSEC = 2, ///< Require DNSSEC data in the answer `````` Michal 'vorner' Vaner committed Aug 25, 2011 181 182 183 `````` ///< (RRSIG, NSEC, etc.). The implementation ///< is allowed to include it even if it is ///< not set. `````` JINMEI Tatuya committed Oct 14, 2011 184 `````` NO_WILDCARD = 4 ///< Do not try wildcard matching. `````` JINMEI Tatuya committed Dec 30, 2010 185 186 `````` }; `````` Michal Vaner committed Dec 21, 2010 187 188 189 190 191 192 193 194 195 `````` /// /// \name Constructors and Destructor. /// //@{ protected: /// The default constructor. /// /// This is intentionally defined as \c protected as this base class should /// never be instantiated (except as part of a derived class). `````` JINMEI Tatuya committed Jul 22, 2011 196 `````` ZoneFinder() {} `````` Michal Vaner committed Dec 21, 2010 197 198 ``````public: /// The destructor. `````` JINMEI Tatuya committed Jul 22, 2011 199 `````` virtual ~ZoneFinder() {} `````` Michal Vaner committed Dec 21, 2010 200 201 202 203 204 205 206 207 `````` //@} /// /// \name Getter Methods /// /// These methods should never throw an exception. //@{ /// Return the origin name of the zone. `````` Michal 'vorner' Vaner committed Aug 01, 2011 208 `````` virtual isc::dns::Name getOrigin() const = 0; `````` Michal Vaner committed Dec 21, 2010 209 210 `````` /// Return the RR class of the zone. `````` Michal 'vorner' Vaner committed Aug 01, 2011 211 `````` virtual isc::dns::RRClass getClass() const = 0; `````` Michal Vaner committed Dec 21, 2010 212 213 214 `````` //@} /// `````` Michal 'vorner' Vaner committed Sep 09, 2011 215 `````` /// \name Search Methods `````` Michal Vaner committed Dec 21, 2010 216 217 218 219 220 221 222 223 `````` /// //@{ /// Search the zone for a given pair of domain name and RR type. /// /// Each derived version of this method searches the underlying backend /// for the data that best matches the given name and type. /// This method is expected to be "intelligent", and identifies the /// best possible answer for the search key. Specifically, `````` JINMEI Tatuya committed Oct 17, 2011 224 `````` /// `````` Michal Vaner committed Dec 21, 2010 225 226 227 228 229 230 231 232 `````` /// - If the search name belongs under a zone cut, it returns the code /// of \c DELEGATION and the NS RRset at the zone cut. /// - If there is no matching name, it returns the code of \c NXDOMAIN, /// and, if DNSSEC is requested, the NSEC RRset that proves the /// non-existence. /// - If there is a matching name but no RRset of the search type, it /// returns the code of \c NXRRSET, and, if DNSSEC is required, /// the NSEC RRset for that name. `````` JINMEI Tatuya committed Jan 18, 2011 233 234 235 `````` /// - If there is a CNAME RR of the searched name but there is no /// RR of the searched type of the name (so this type is different from /// CNAME), it returns the code of \c CNAME and that CNAME RR. `````` JINMEI Tatuya committed Jan 19, 2011 236 `````` /// Note that if the searched RR type is CNAME, it is considered `````` JINMEI Tatuya committed Jan 18, 2011 237 `````` /// a successful match, and the code of \c SUCCESS will be returned. `````` Michal Vaner committed Dec 21, 2010 238 239 `````` /// - If the search name matches a delegation point of DNAME, it returns /// the code of \c DNAME and that DNAME RR. `````` Michal 'vorner' Vaner committed Jan 25, 2011 240 241 242 `````` /// - If the target isn't NULL, all RRsets under the domain are inserted /// there and SUCCESS (or NXDOMAIN, in case of empty domain) is returned /// instead of normall processing. This is intended to handle ANY query. `````` JINMEI Tatuya committed Oct 17, 2011 243 244 245 246 `````` /// /// \note This behavior is controversial as we discussed in /// https://lists.isc.org/pipermail/bind10-dev/2011-January/001918.html /// We should revisit the interface before we heavily rely on it. `````` Michal Vaner committed Dec 21, 2010 247 `````` /// `````` JINMEI Tatuya committed Dec 30, 2010 248 `````` /// The \c options parameter specifies customized behavior of the search. `````` Michal 'vorner' Vaner committed Sep 09, 2011 249 `````` /// Their semantics is as follows (they are or bit-field): `````` JINMEI Tatuya committed Oct 17, 2011 250 `````` /// `````` Michal 'vorner' Vaner committed Sep 09, 2011 251 `````` /// - \c FIND_GLUE_OK Allow search under a zone cut. By default the search `````` JINMEI Tatuya committed Dec 30, 2010 252 253 254 255 256 257 258 `````` /// will stop once it encounters a zone cut. If this option is specified /// it remembers information about the highest zone cut and continues /// the search until it finds an exact match for the given name or it /// detects there is no exact match. If an exact match is found, /// RRsets for that name are searched just like the normal case; /// otherwise, if the search has encountered a zone cut, \c DELEGATION /// with the information of the highest zone cut will be returned. `````` Michal 'vorner' Vaner committed Sep 09, 2011 259 260 261 `````` /// - \c FIND_DNSSEC Request that DNSSEC data (like NSEC, RRSIGs) are /// returned with the answer. It is allowed for the data source to /// include them even when not requested. `````` JINMEI Tatuya committed Oct 14, 2011 262 263 264 265 `````` /// - \c NO_WILDCARD Do not try wildcard matching. This option is of no /// use for normal lookups; it's intended to be used to get a DNSSEC /// proof of the non existence of any matching wildcard or non existence /// of an exact match when a wildcard match is found. `````` JINMEI Tatuya committed Dec 30, 2010 266 `````` /// `````` Michal Vaner committed Dec 21, 2010 267 268 269 `````` /// A derived version of this method may involve internal resource /// allocation, especially for constructing the resulting RRset, and may /// throw an exception if it fails. `````` chenzhengzhang committed Jan 25, 2011 270 271 `````` /// It throws DuplicateRRset exception if there are duplicate rrsets under /// the same domain. `````` Michal Vaner committed Dec 21, 2010 272 273 274 275 `````` /// It should not throw other types of exceptions. /// /// \param name The domain name to be searched for. /// \param type The RR type to be searched for. `````` chenzhengzhang committed Jan 25, 2011 276 277 `````` /// \param target If target is not NULL, insert all RRs under the domain /// into it. `````` JINMEI Tatuya committed Dec 30, 2010 278 `````` /// \param options The search options. `````` Michal Vaner committed Dec 21, 2010 279 280 `````` /// \return A \c FindResult object enclosing the search result (see above). virtual FindResult find(const isc::dns::Name& name, `````` JINMEI Tatuya committed Dec 30, 2010 281 `````` const isc::dns::RRType& type, `````` chenzhengzhang committed Jan 25, 2011 282 `````` isc::dns::RRsetList* target = NULL, `````` JINMEI Tatuya committed Dec 30, 2010 283 `````` const FindOptions options `````` Jelte Jansen committed Aug 11, 2011 284 `````` = FIND_DEFAULT) = 0; `````` Michal 'vorner' Vaner committed Sep 09, 2011 285 286 287 `````` /// \brief Get previous name in the zone /// `````` Michal 'vorner' Vaner committed Sep 20, 2011 288 `````` /// Gets the previous name in the DNSSEC order. This can be used `````` 289 `````` /// to find the correct NSEC records for proving nonexistence `````` Michal 'vorner' Vaner committed Sep 09, 2011 290 291 292 293 294 295 `````` /// of domains. /// /// The concrete implementation might throw anything it thinks appropriate, /// however it is recommended to stick to the ones listed here. The user /// of this method should be able to handle any exceptions. /// `````` Michal 'vorner' Vaner committed Sep 23, 2011 296 297 `````` /// This method does not include under-zone-cut data (glue data). /// `````` Michal 'vorner' Vaner committed Sep 09, 2011 298 299 300 301 302 `````` /// \param query The name for which one we look for a previous one. The /// queried name doesn't have to exist in the zone. /// \return The preceding name /// /// \throw NotImplemented in case the data source backend doesn't support `````` Michal 'vorner' Vaner committed Sep 23, 2011 303 304 `````` /// DNSSEC or there is no previous in the zone (NSEC records might be /// missing in the DB, the queried name is less or equal to the apex). `````` Michal 'vorner' Vaner committed Sep 09, 2011 305 306 307 308 309 `````` /// \throw DataSourceError for low-level or internal datasource errors /// (like broken connection to database, wrong data living there). /// \throw std::bad_alloc For allocation errors. virtual isc::dns::Name findPreviousName(const isc::dns::Name& query) const = 0; `````` Michal Vaner committed Dec 21, 2010 310 311 312 `````` //@} }; `````` Michal 'vorner' Vaner committed Sep 06, 2011 313 314 315 316 317 318 319 320 321 ``````/// \brief Operator to combine FindOptions /// /// We would need to manually static-cast the options if we put or /// between them, which is undesired with bit-flag options. Therefore /// we hide the cast here, which is the simplest solution and it still /// provides reasonable level of type safety. inline ZoneFinder::FindOptions operator |(ZoneFinder::FindOptions a, ZoneFinder::FindOptions b) { `````` Michal 'vorner' Vaner committed Sep 06, 2011 322 323 `````` return (static_cast(static_cast(a) | static_cast(b))); `````` Michal 'vorner' Vaner committed Sep 06, 2011 324 325 ``````} `````` JINMEI Tatuya committed Jul 22, 2011 326 327 ``````/// \brief A pointer-like type pointing to a \c ZoneFinder object. typedef boost::shared_ptr ZoneFinderPtr; `````` Michal Vaner committed Dec 21, 2010 328 `````` `````` JINMEI Tatuya committed Jul 22, 2011 329 330 ``````/// \brief A pointer-like type pointing to a \c ZoneFinder object. typedef boost::shared_ptr ConstZoneFinderPtr; `````` Michal Vaner committed Dec 21, 2010 331 `````` `````` JINMEI Tatuya committed Aug 12, 2011 332 ``````/// The base class to make updates to a single zone. `````` JINMEI Tatuya committed Aug 27, 2011 333 334 335 336 ``````/// /// On construction, each derived class object will start a "transaction" /// for making updates to a specific zone (this means a constructor of /// a derived class would normally take parameters to identify the zone `````` JINMEI Tatuya committed Sep 06, 2011 337 ``````/// to be updated). The underlying realization of a "transaction" will differ `````` JINMEI Tatuya committed Aug 27, 2011 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 ``````/// for different derived classes; if it uses a general purpose database /// as a backend, it will involve performing some form of "begin transaction" /// statement for the database. /// /// Updates (adding or deleting RRs) are made via \c addRRset() and /// \c deleteRRset() methods. Until the \c commit() method is called the /// changes are local to the updater object. For example, they won't be /// visible via a \c ZoneFinder object except the one returned by the /// updater's own \c getFinder() method. The \c commit() completes the /// transaction and makes the changes visible to others. /// /// This class does not provide an explicit "rollback" interface. If /// something wrong or unexpected happens during the updates and the /// caller wants to cancel the intermediate updates, the caller should /// simply destruct the updater object without calling \c commit(). /// The destructor is supposed to perform the "rollback" operation, /// depending on the internal details of the derived class. /// /// \note This initial implementation provides a quite simple interface of /// adding and deleting RRs (see the description of the related methods). /// It may be revisited as we gain more experiences. `````` JINMEI Tatuya committed Aug 12, 2011 359 ``````class ZoneUpdater { `````` JINMEI Tatuya committed Aug 12, 2011 360 ``````protected: `````` JINMEI Tatuya committed Aug 27, 2011 361 362 363 364 `````` /// The default constructor. /// /// This is intentionally defined as protected to ensure that this base /// class is never instantiated directly. `````` JINMEI Tatuya committed Aug 12, 2011 365 366 `````` ZoneUpdater() {} `````` JINMEI Tatuya committed Aug 12, 2011 367 ``````public: `````` JINMEI Tatuya committed Aug 27, 2011 368 369 370 371 372 `````` /// The destructor /// /// Each derived class implementation must ensure that if \c commit() /// has not been performed by the time of the call to it, then it /// "rollbacks" the updates made via the updater so far. `````` JINMEI Tatuya committed Aug 12, 2011 373 374 `````` virtual ~ZoneUpdater() {} `````` JINMEI Tatuya committed Aug 27, 2011 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 `````` /// Return a finder for the zone being updated. /// /// The returned finder provides the functionalities of \c ZoneFinder /// for the zone as updates are made via the updater. That is, before /// making any update, the finder will be able to find all RRsets that /// exist in the zone at the time the updater is created. If RRsets /// are added or deleted via \c addRRset() or \c deleteRRset(), /// this finder will find the added ones or miss the deleted ones /// respectively. /// /// The finder returned by this method is effective only while the updates /// are performed, i.e., from the construction of the corresponding /// updater until \c commit() is performed or the updater is destructed /// without commit. The result of a subsequent call to this method (or /// the use of the result) after that is undefined. `````` JINMEI Tatuya committed Aug 16, 2011 390 `````` /// `````` JINMEI Tatuya committed Aug 27, 2011 391 `````` /// \return A reference to a \c ZoneFinder for the updated zone `````` JINMEI Tatuya committed Aug 12, 2011 392 `````` virtual ZoneFinder& getFinder() = 0; `````` JINMEI Tatuya committed Aug 12, 2011 393 `````` `````` JINMEI Tatuya committed Aug 27, 2011 394 395 396 397 398 399 400 401 `````` /// Add an RRset to a zone via the updater /// /// This may be revisited in a future version, but right now the intended /// behavior of this method is simple: It "naively" adds the specified /// RRset to the zone specified on creation of the updater. /// It performs minimum level of validation on the specified RRset: /// - Whether the RR class is identical to that for the zone to be updated /// - Whether the RRset is not empty, i.e., it has at least one RDATA `````` JINMEI Tatuya committed Sep 06, 2011 402 403 `````` /// - Whether the RRset is not associated with an RRSIG, i.e., /// whether \c getRRsig() on the RRset returns a NULL pointer. `````` JINMEI Tatuya committed Aug 27, 2011 404 405 406 407 408 409 410 411 412 413 `````` /// /// and otherwise does not check any oddity. For example, it doesn't /// check whether the owner name of the specified RRset is a subdomain /// of the zone's origin; it doesn't care whether or not there is already /// an RRset of the same name and RR type in the zone, and if there is, /// whether any of the existing RRs have duplicate RDATA with the added /// ones. If these conditions matter the calling application must examine /// the existing data beforehand using the \c ZoneFinder returned by /// \c getFinder(). /// `````` JINMEI Tatuya committed Sep 06, 2011 414 415 416 417 418 419 `````` /// The validation requirement on the associated RRSIG is temporary. /// If we find it more reasonable and useful to allow adding a pair of /// RRset and its RRSIG RRset as we gain experiences with the interface, /// we may remove this restriction. Until then we explicitly check it /// to prevent accidental misuse. /// `````` JINMEI Tatuya committed Aug 27, 2011 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 `````` /// Conceptually, on successful call to this method, the zone will have /// the specified RRset, and if there is already an RRset of the same /// name and RR type, these two sets will be "merged". "Merged" means /// that a subsequent call to \c ZoneFinder::find() for the name and type /// will result in success and the returned RRset will contain all /// previously existing and newly added RDATAs with the TTL being the /// minimum of the two RRsets. The underlying representation of the /// "merged" RRsets may vary depending on the characteristic of the /// underlying data source. For example, if it uses a general purpose /// database that stores each RR of the same RRset separately, it may /// simply be a larger sets of RRs based on both the existing and added /// RRsets; the TTLs of the RRs may be different within the database, and /// there may even be duplicate RRs in different database rows. As long /// as the RRset returned via \c ZoneFinder::find() conforms to the /// concept of "merge", the actual internal representation is up to the /// implementation. `````` JINMEI Tatuya committed Aug 16, 2011 436 `````` /// `````` JINMEI Tatuya committed Aug 27, 2011 437 438 439 `````` /// This method must not be called once commit() is performed. If it /// calls after \c commit() the implementation must throw a /// \c DataSourceError exception. `````` JINMEI Tatuya committed Aug 16, 2011 440 `````` /// `````` Michal 'vorner' Vaner committed Nov 08, 2011 441 442 443 444 `````` /// If journaling was requested when getting this updater, it might reject /// to add the RRset if the squence doesn't look like and IXFR. In such /// such case isc::BadValue is thrown. /// `````` JINMEI Tatuya committed Aug 27, 2011 445 446 `````` /// \todo As noted above we may have to revisit the design details as we /// gain experiences: `````` JINMEI Tatuya committed Aug 16, 2011 447 `````` /// `````` JINMEI Tatuya committed Aug 27, 2011 448 449 450 451 452 453 454 455 456 457 `````` /// - we may want to check (and maybe reject) if there is already a /// duplicate RR (that has the same RDATA). /// - we may want to check (and maybe reject) if there is already an /// RRset of the same name and RR type with different TTL /// - we may even want to check if there is already any RRset of the /// same name and RR type. /// - we may want to add an "options" parameter that can control the /// above points /// - we may want to have this method return a value containing the /// information on whether there's a duplicate, etc. `````` JINMEI Tatuya committed Aug 16, 2011 458 `````` /// `````` JINMEI Tatuya committed Aug 27, 2011 459 460 `````` /// \exception DataSourceError Called after \c commit(), RRset is invalid /// (see above), internal data source error `````` Michal 'vorner' Vaner committed Nov 08, 2011 461 462 `````` /// \exception isc::BadValue Journaling is enabled and the current RRset /// doesn't fit into the IXFR sequence (see above). `````` JINMEI Tatuya committed Aug 27, 2011 463 464 465 `````` /// \exception std::bad_alloc Resource allocation failure /// /// \param rrset The RRset to be added `````` JINMEI Tatuya committed Aug 16, 2011 466 467 `````` virtual void addRRset(const isc::dns::RRset& rrset) = 0; `````` JINMEI Tatuya committed Aug 27, 2011 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 `````` /// Delete an RRset from a zone via the updater /// /// Like \c addRRset(), the detailed semantics and behavior of this method /// may have to be revisited in a future version. The following are /// based on the initial implementation decisions. /// /// On successful completion of this method, it will remove from the zone /// the RRs of the specified owner name and RR type that match one of /// the RDATAs of the specified RRset. There are several points to be /// noted: /// - Existing RRs that don't match any of the specified RDATAs will /// remain in the zone. /// - Any RRs of the specified RRset that doesn't exist in the zone will /// simply be ignored; the implementation of this method is not supposed /// to check that condition. /// - The TTL of the RRset is ignored; matching is only performed by /// the owner name, RR type and RDATA /// /// Ignoring the TTL may not look sensible, but it's based on the /// observation that it will result in more intuitive result, especially /// when the underlying data source is a general purpose database. /// See also \c DatabaseAccessor::deleteRecordInZone() on this point. /// It also matches the dynamic update protocol (RFC2136), where TTLs /// are ignored when deleting RRs. /// /// \note Since the TTL is ignored, this method could take the RRset /// to be deleted as a tuple of name, RR type, and a list of RDATAs. /// But in practice, it's quite likely that the caller has the RRset /// in the form of the \c RRset object (e.g., extracted from a dynamic /// update request message), so this interface would rather be more /// convenient. If it turns out not to be true we can change or extend /// the method signature. /// /// This method performs minimum level of validation on the specified /// RRset: /// - Whether the RR class is identical to that for the zone to be updated /// - Whether the RRset is not empty, i.e., it has at least one RDATA `````` JINMEI Tatuya committed Sep 06, 2011 505 506 `````` /// - Whether the RRset is not associated with an RRSIG, i.e., /// whether \c getRRsig() on the RRset returns a NULL pointer. `````` JINMEI Tatuya committed Aug 17, 2011 507 `````` /// `````` JINMEI Tatuya committed Aug 27, 2011 508 509 510 511 `````` /// This method must not be called once commit() is performed. If it /// calls after \c commit() the implementation must throw a /// \c DataSourceError exception. /// `````` Michal 'vorner' Vaner committed Nov 08, 2011 512 513 514 515 `````` /// If journaling was requested when getting this updater, it might reject /// to add the RRset if the squence doesn't look like and IXFR. In such /// such case isc::BadValue is thrown. /// `````` JINMEI Tatuya committed Aug 27, 2011 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 `````` /// \todo As noted above we may have to revisit the design details as we /// gain experiences: /// /// - we may want to check (and maybe reject) if some or all of the RRs /// for the specified RRset don't exist in the zone /// - we may want to allow an option to "delete everything" for specified /// name and/or specified name + RR type. /// - as mentioned above, we may want to include the TTL in matching the /// deleted RRs /// - we may want to add an "options" parameter that can control the /// above points /// - we may want to have this method return a value containing the /// information on whether there's any RRs that are specified but don't /// exit, the number of actually deleted RRs, etc. /// /// \exception DataSourceError Called after \c commit(), RRset is invalid /// (see above), internal data source error `````` Michal 'vorner' Vaner committed Nov 08, 2011 533 534 `````` /// \exception isc::BadValue Journaling is enabled and the current RRset /// doesn't fit into the IXFR sequence (see above). `````` JINMEI Tatuya committed Aug 27, 2011 535 536 537 `````` /// \exception std::bad_alloc Resource allocation failure /// /// \param rrset The RRset to be deleted `````` JINMEI Tatuya committed Aug 17, 2011 538 539 `````` virtual void deleteRRset(const isc::dns::RRset& rrset) = 0; `````` JINMEI Tatuya committed Aug 27, 2011 540 541 542 543 544 545 546 547 548 `````` /// Commit the updates made in the updater to the zone /// /// This method completes the "transaction" started at the creation /// of the updater. After successful completion of this method, the /// updates will be visible outside the scope of the updater. /// The actual internal behavior will defer for different derived classes. /// For a derived class with a general purpose database as a backend, /// for example, this method would perform a "commit" statement for the /// database. `````` JINMEI Tatuya committed Aug 12, 2011 549 550 551 `````` /// /// This operation can only be performed at most once. A duplicate call /// must result in a DatasourceError exception. `````` JINMEI Tatuya committed Aug 27, 2011 552 553 554 `````` /// /// \exception DataSourceError Duplicate call of the method, /// internal data source error `````` JINMEI Tatuya committed Aug 12, 2011 555 `````` virtual void commit() = 0; `````` JINMEI Tatuya committed Aug 12, 2011 556 557 558 559 560 561 562 ``````}; /// \brief A pointer-like type pointing to a \c ZoneUpdater object. typedef boost::shared_ptr ZoneUpdaterPtr; } // end of datasrc } // end of isc `````` Michal Vaner committed Dec 21, 2010 563 `````` `````` JINMEI Tatuya committed Dec 30, 2010 564 565 566 567 568 ``````#endif // __ZONE_H // Local Variables: // mode: c++ // End:``````