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 __RRPARAMREGISTRY_H
16 : : #define __RRPARAMREGISTRY_H 1
17 : :
18 : : #include <string>
19 : :
20 : : #include <stdint.h>
21 : :
22 : : #include <boost/shared_ptr.hpp>
23 : :
24 : : #include <exceptions/exceptions.h>
25 : :
26 : : #include <dns/rdata.h>
27 : :
28 : : namespace isc {
29 : : namespace dns {
30 : :
31 : : // forward declarations
32 : : struct RRParamRegistryImpl;
33 : :
34 : : ///
35 : : /// \brief A standard DNS module exception that is thrown if a new RR type is
36 : : /// being registered with a different type string.
37 : : ///
38 : 1 : class RRTypeExists : public Exception {
39 : : public:
40 : : RRTypeExists(const char* file, size_t line, const char* what) :
41 [ + - ]: 1 : isc::Exception(file, line, what) {}
42 : : };
43 : :
44 : : ///
45 : : /// \brief A standard DNS module exception that is thrown if a new RR class is
46 : : /// being registered with a different type string.
47 : : ///
48 : 1 : class RRClassExists : public Exception {
49 : : public:
50 : : RRClassExists(const char* file, size_t line, const char* what) :
51 [ + - ]: 1 : isc::Exception(file, line, what) {}
52 : : };
53 : :
54 : : namespace rdata {
55 : : /// \brief The \c AbstractRdataFactory class is an abstract base class to
56 : : /// encapsulate a set of Rdata factory methods in a polymorphic way.
57 : : ///
58 : : /// An external developers who want to introduce a new or experimental RR type
59 : : /// are expected to define a corresponding derived class of \c
60 : : /// AbstractRdataFactory and register it via \c RRParamRegistry.
61 : : ///
62 : : /// For other users of this API normally do not have to care about this class
63 : : /// or its derived classes; this class is generally intended to be used
64 : : /// as an internal utility of the API implementation.
65 : : class AbstractRdataFactory {
66 : : ///
67 : : /// \name Constructors and Destructor
68 : : ///
69 : : //@{
70 : : protected:
71 : : /// The default constructor
72 : : ///
73 : : /// This is intentionally defined as \c protected as this base class should
74 : : /// never be instantiated (except as part of a derived class).
75 : 1379 : AbstractRdataFactory() {}
76 : : public:
77 : : /// The destructor.
78 : 1379 : virtual ~AbstractRdataFactory() {};
79 : : //@}
80 : :
81 : : ///
82 : : /// \name Factory methods for polymorphic creation.
83 : : ///
84 : : //@{
85 : : ///
86 : : /// \brief Create RDATA from a string.
87 : : ///
88 : : /// This method creates from a string an \c Rdata object of specific class
89 : : /// corresponding to the specific derived class of \c AbstractRdataFactory.
90 : : ///
91 : : /// \param rdata_str A string of textual representation of the \c Rdata.
92 : : /// \return An \c RdataPtr object pointing to the created \c Rdata object.
93 : : virtual RdataPtr create(const std::string& rdata_str) const = 0;
94 : : ///
95 : : /// \brief Create RDATA from wire-format data.
96 : : ///
97 : : /// This method creates from wire-format binary data an \c Rdata object
98 : : /// of specific class corresponding to the specific derived class of
99 : : /// \c AbstractRdataFactory.
100 : : ///
101 : : /// \param buffer A reference to an \c InputBuffer object storing the
102 : : /// \c Rdata to parse.
103 : : /// \param rdata_len The length in buffer of the \c Rdata. In bytes.
104 : : /// \return An \c RdataPtr object pointing to the created \c Rdata object.
105 : : virtual RdataPtr create(isc::util::InputBuffer& buffer, size_t rdata_len) const = 0;
106 : : ///
107 : : /// \brief Create RDATA from another \c Rdata object of the same type.
108 : : ///
109 : : /// This method creates an \c Rdata object of specific class corresponding
110 : : /// to the specific derived class of \c AbstractRdataFactory, copying the
111 : : /// content of the given \c Rdata, \c source.
112 : : ///
113 : : /// \c source must be an object of the concrete derived class corresponding
114 : : /// to the specific derived class of \c AbstractRdataFactory;
115 : : /// otherwise, an exception of class \c std::bad_cast will be thrown.
116 : : ///
117 : : /// \param source A reference to an \c Rdata object whose content is to
118 : : /// be copied to the created \c Rdata object.
119 : : /// \return An \c RdataPtr object pointing to the created \c Rdata object.
120 : : virtual RdataPtr create(const rdata::Rdata& source) const = 0;
121 : : //@}
122 : : };
123 : :
124 : : ///
125 : : /// The \c RdataFactoryPtr type is a pointer-like type, pointing to an
126 : : /// object of some concrete derived class of \c AbstractRdataFactory.
127 : : ///
128 : : typedef boost::shared_ptr<AbstractRdataFactory> RdataFactoryPtr;
129 : : } // end of namespace rdata
130 : :
131 : : ///
132 : : /// The \c RRParamRegistry class represents a registry of parameters to
133 : : /// manipulate DNS resource records (RRs).
134 : : ///
135 : : /// A \c RRParamRegistry class object stores a mapping between RR types or
136 : : /// classes and their textual representations. It will also have knowledge of
137 : : /// how to create an RDATA object for a specific pair of RR type and class
138 : : /// (not implemented in this version).
139 : : ///
140 : : /// Normal applications that only handle standard DNS protocols won't have to
141 : : /// care about this class. This is mostly an internal class to the DNS library
142 : : /// to manage standard parameters. Some advanced applications may still need
143 : : /// to use this class explicitly. For example, if an application wants to
144 : : /// define and use an experimental non-standard RR type, it may want to register
145 : : /// related protocol parameters for its convenience. This class is designed to
146 : : /// allow such usage without modifying the library source code or rebuilding
147 : : /// the library.
148 : : ///
149 : : /// It is assumed that at most one instance of this class can exist so that
150 : : /// the application uses the consistent set of registered parameters. To ensure
151 : : /// this, this class is designed and implemented as a "singleton class": the
152 : : /// constructor is intentionally private, and applications must get access to
153 : : /// the single instance via the \c getRegistry() static member function.
154 : : ///
155 : : /// In the current implementation, access to the singleton \c RRParamRegistry
156 : : /// object is not thread safe.
157 : : /// The application should ensure that multiple threads don't race in the
158 : : /// first invocation of \c getRegistry(), and, if the registry needs to
159 : : /// be changed dynamically, read and write operations are performed
160 : : /// exclusively.
161 : : /// Since this class should be static in common usage this restriction would
162 : : /// be acceptable in practice.
163 : : /// In the future, we may extend the implementation so that multiple threads can
164 : : /// get access to the registry fully concurrently without any restriction.
165 : : ///
166 : : /// Note: the implementation of this class is incomplete: we should at least
167 : : /// add RDATA related parameters. This will be done in a near future version,
168 : : /// at which point some of method signatures will be changed.
169 : : class RRParamRegistry {
170 : : ///
171 : : /// \name Constructors and Destructor
172 : : ///
173 : : /// These are intentionally hidden (see the class description).
174 : : //@{
175 : : private:
176 : : RRParamRegistry();
177 : : RRParamRegistry(const RRParamRegistry& orig);
178 : : ~RRParamRegistry();
179 : : //@}
180 : : public:
181 : : ///
182 : : /// \brief Return the singleton instance of \c RRParamRegistry.
183 : : ///
184 : : /// This method is a unified access point to the singleton instance of
185 : : /// the RR parameter registry (\c RRParamRegistry).
186 : : /// On first invocation it internally constructs an instance of the
187 : : /// \c RRParamRegistry class and returns a reference to it.
188 : : /// This is a static object inside this method and will remain valid
189 : : /// throughout the rest of the application lifetime.
190 : : /// On subsequent calls this method simply returns a reference to the
191 : : /// singleton object.
192 : : ///
193 : : /// If resource allocation fails in the first invocation,
194 : : /// a corresponding standard exception will be thrown.
195 : : /// This method never fails otherwise. In particular, this method
196 : : /// doesn't throw an exception once the singleton instance is constructed.
197 : : ///
198 : : /// \return A reference to the singleton instance of \c RRParamRegistry.
199 : : static RRParamRegistry& getRegistry();
200 : :
201 : : ///
202 : : /// \name Registry Update Methods
203 : : ///
204 : : //@{
205 : : ///
206 : : /// \brief Add a set of parameters for a pair of RR type and class.
207 : : ///
208 : : /// This method adds to the registry a specified set of RR parameters,
209 : : /// including mappings between type/class codes and their textual
210 : : /// representations.
211 : : ///
212 : : /// Regarding the mappings between textual representations and integer
213 : : /// codes, this method behaves in the same way as \c addType() and
214 : : /// \c addClass(). That is, it ignores any overriding attempt as
215 : : /// long as the mapping is the same; otherwise the corresponding exception
216 : : /// will be thrown.
217 : : ///
218 : : /// This method provides the strong exception guarantee: unless an
219 : : /// exception is thrown the entire specified set of parameters must be
220 : : /// stored in the registry; if this method throws an exception the
221 : : /// registry will remain in the state before this method is called.
222 : : ///
223 : : /// \param type_string The textual representation of the RR type.
224 : : /// \param type_code The integer code of the RR type.
225 : : /// \param class_string The textual representation of the RR class.
226 : : /// \param class_code The integer code of the RR class.
227 : : /// \param rdata_factory An \c RdataFactoryPtr object pointing to a
228 : : /// concrete RDATA factory.
229 : : void add(const std::string& type_string, uint16_t type_code,
230 : : const std::string& class_string, uint16_t class_code,
231 : : rdata::RdataFactoryPtr rdata_factory);
232 : :
233 : : /// \brief Add a set of parameters for a class-independent RR type.
234 : : ///
235 : : /// This method behaves as exactly same as the other \c add method except
236 : : /// that it handles class-independent types (such as NS, CNAME, or SOA).
237 : : ///
238 : : /// \param type_string The textual representation of the RR type.
239 : : /// \param type_code The integer code of the RR type.
240 : : /// \param rdata_factory An \c RdataFactoryPtr object pointing to a
241 : : /// concrete RDATA factory.
242 : : void add(const std::string& type_string, uint16_t type_code,
243 : : rdata::RdataFactoryPtr rdata_factory);
244 : :
245 : : /// \brief Add mappings between RR type code and textual representation.
246 : : ///
247 : : /// This method adds a mapping from the type code of an RR to its textual
248 : : /// representation and the reverse mapping in the registry.
249 : : ///
250 : : /// If the given RR type is already registered with the same textual
251 : : /// representation, this method simply ignores the duplicate mapping;
252 : : /// if the given type is registered and a new pair with a different
253 : : /// textual representation is being added,an exception of class
254 : : /// \c RRTypeExist will be thrown.
255 : : /// To replace an existing mapping with a different textual representation,
256 : : /// the existing one must be removed by the \c removeType() method
257 : : /// beforehand.
258 : : ///
259 : : /// In addition, if resource allocation for the new mapping entries fails,
260 : : /// a corresponding standard exception will be thrown.
261 : : ///
262 : : /// This method provides the strong exception guarantee: unless an exception
263 : : /// is thrown the specified mappings must be stored in the registry
264 : : /// (although it may be an already existing one) on completion of the
265 : : /// method; if this method throws an exception the registry will remain
266 : : /// in the state before this method is called.
267 : : ///
268 : : /// \param type_string The textual representation of the RR type.
269 : : /// \param type_code The integer code of the RR type.
270 : : /// \return \c true if a new mapping is added to the repository; \c false
271 : : /// if the same mapping is already registered.
272 : : bool addType(const std::string& type_string, uint16_t type_code);
273 : :
274 : : /// \brief Remove mappings between RR type code and textual representation
275 : : /// for a given type.
276 : : ///
277 : : /// This method can safely be called whether or not the specified mappings
278 : : /// exist in the registry. If not, this method simply ignores the attempt
279 : : /// and returns \c false.
280 : : ///
281 : : /// This method never throws an exception.
282 : : ///
283 : : /// \param type_code The integer code of the RR type.
284 : : /// \return \c true if mappings for the specified RR type exists and is
285 : : /// removed; \c false if no such mapping is in the registry.
286 : : bool removeType(uint16_t type_code);
287 : :
288 : : /// \brief Add mappings between RR class code and textual representation.
289 : : ///
290 : : /// This method adds a mapping from the class code of an RR to its textual
291 : : /// representation and the reverse mapping in the registry.
292 : : ///
293 : : /// If the given RR class is already registered with the same textual
294 : : /// representation, this method simply ignores the duplicate mapping;
295 : : /// if the given class is registered and a new pair with a different
296 : : /// textual representation is being added,an exception of class
297 : : /// \c RRClassExist will be thrown.
298 : : /// To replace an existing mapping with a different textual representation,
299 : : /// the existing one must be removed by the \c removeClass() method
300 : : /// beforehand.
301 : : ///
302 : : /// In addition, if resource allocation for the new mapping entries fails,
303 : : /// a corresponding standard exception will be thrown.
304 : : ///
305 : : /// This method provides the strong exception guarantee: unless an exception
306 : : /// is thrown the specified mappings must be stored in the registry
307 : : /// (although it may be an already existing one) on completion of the
308 : : /// method; if this method throws an exception the registry will remain
309 : : /// in the state before this method is called.
310 : : ///
311 : : /// \param class_string The textual representation of the RR class.
312 : : /// \param class_code The integer code of the RR class.
313 : : /// \return \c true if a new mapping is added to the repository; \c false
314 : : /// if the same mapping is already registered.
315 : : bool addClass(const std::string& class_string, uint16_t class_code);
316 : :
317 : : /// \brief Remove mappings between RR class code and textual representation
318 : : /// for a given class.
319 : : ///
320 : : /// This method can safely be called whether or not the specified mappings
321 : : /// exist in the registry. If not, this method simply ignores the attempt
322 : : /// and returns \c false.
323 : : ///
324 : : /// This method never throws an exception.
325 : : ///
326 : : /// \param class_code The integer code of the RR class.
327 : : /// \return \c true if mappings for the specified RR type exists and is
328 : : /// removed; \c false if no such mapping is in the registry.
329 : : bool removeClass(uint16_t class_code);
330 : :
331 : : /// \brief Remove registered RDATA factory for the given pair of \c RRType
332 : : /// and \c RRClass.
333 : : ///
334 : : /// This method can safely be called whether or not the specified factory
335 : : /// object exist in the registry. If not, this method simply ignores the
336 : : /// attempt and returns \c false.
337 : : ///
338 : : /// This method never throws an exception.
339 : : ///
340 : : /// \param rrtype An \c RRType object specifying the type/class pair.
341 : : /// \param rrclass An \c RRClass object specifying the type/class pair.
342 : : /// \return \c true if a factory object for the specified RR type/class
343 : : /// pair exists and is removed; \c false if no such object is in the
344 : : /// registry.
345 : : bool removeRdataFactory(const RRType& rrtype, const RRClass& rrclass);
346 : :
347 : : /// \brief Remove registered RDATA factory for the given pair of \c RRType
348 : : /// and \c RRClass.
349 : : ///
350 : : /// This method can safely be called whether or not the specified factory
351 : : /// object exist in the registry. If not, this method simply ignores the
352 : : /// attempt and returns \c false.
353 : : ///
354 : : /// This method never throws an exception.
355 : : ///
356 : : /// \param rrtype An \c RRType object specifying the type/class pair.
357 : : /// \return \c true if a factory object for the specified RR type/class
358 : : /// pair exists and is removed; \c false if no such object is in the
359 : : /// registry.
360 : : bool removeRdataFactory(const RRType& rrtype);
361 : : //@}
362 : :
363 : : ///
364 : : /// \name Parameter Conversion Methods
365 : : ///
366 : : //@{
367 : : /// \brief Convert a textual representation of an RR type to the
368 : : /// corresponding 16-bit integer code.
369 : : ///
370 : : /// This method searches the \c RRParamRegistry for the mapping from the
371 : : /// given textual representation of RR type to the corresponding integer
372 : : /// code. If a mapping is found, it returns the associated type code;
373 : : /// otherwise, if the given string is in the form of "TYPEnnnn", it returns
374 : : /// the corresponding number as the type code; otherwise, it throws an
375 : : /// exception of class \c InvalidRRType.
376 : : ///
377 : : /// \param type_string The textual representation of the RR type.
378 : : /// \return The RR type code for \c type_string.
379 : : uint16_t textToTypeCode(const std::string& type_string) const;
380 : :
381 : : /// \brief Convert type code into its textual representation.
382 : : ///
383 : : /// This method searches the \c RRParamRegistry for the mapping from the
384 : : /// given RR type code to its textual representation.
385 : : /// If a mapping is found, it returns (a copy of) the associated string;
386 : : /// otherwise, this method creates a new string in the form of "TYPEnnnn"
387 : : /// where "nnnn" is the decimal representation of the type code, and
388 : : /// returns the new string.
389 : : ///
390 : : /// If resource allocation for the returned string fails,
391 : : /// a corresponding standard exception will be thrown.
392 : : /// This method never fails otherwise.
393 : : ///
394 : : /// \param type_code The integer code of the RR type.
395 : : /// \return A textual representation of the RR type for code \c type_code.
396 : : std::string codeToTypeText(uint16_t type_code) const;
397 : :
398 : : /// \brief Convert a textual representation of an RR class to the
399 : : /// corresponding 16-bit integer code.
400 : : ///
401 : : /// This method searches the \c RRParamRegistry for the mapping from the
402 : : /// given textual representation of RR class to the corresponding integer
403 : : /// code. If a mapping is found, it returns the associated class code;
404 : : /// otherwise, if the given string is in the form of "CLASSnnnn", it returns
405 : : /// the corresponding number as the class code; otherwise, it throws an
406 : : /// exception of class \c InvalidRRClass.
407 : : ///
408 : : /// \param class_string The textual representation of the RR class.
409 : : /// \return The RR class code for \c class_string.
410 : : uint16_t textToClassCode(const std::string& class_string) const;
411 : :
412 : : /// \brief Convert class code into its textual representation.
413 : : ///
414 : : /// This method searches the \c RRParamRegistry for the mapping from the
415 : : /// given RR class code to its textual representation.
416 : : /// If a mapping is found, it returns (a copy of) the associated string;
417 : : /// otherwise, this method creates a new string in the form of "CLASSnnnn"
418 : : /// where "nnnn" is the decimal representation of the class code, and
419 : : /// returns the new string.
420 : : ///
421 : : /// If resource allocation for the returned string fails,
422 : : /// a corresponding standard exception will be thrown.
423 : : /// This method never fails otherwise.
424 : : ///
425 : : /// \param class_code The integer code of the RR class.
426 : : /// \return A textual representation of the RR class for code \c class_code.
427 : : std::string codeToClassText(uint16_t class_code) const;
428 : : //@}
429 : :
430 : : ///
431 : : /// \name RDATA Factories
432 : : ///
433 : : /// This set of methods provide a unified interface to create an
434 : : /// \c rdata::Rdata object in a parameterized polymorphic way,
435 : : /// that is, these methods take a pair of \c RRType and \c RRClass
436 : : /// objects and data specific to that pair, and create an object of
437 : : /// the corresponding concrete derived class of \c rdata::Rdata.
438 : : ///
439 : : /// These methods first search the \c RRParamRegistry for a factory
440 : : /// method (a member of a concrete derived class of
441 : : /// \c AbstractRdataFactory) for the given RR type and class pair.
442 : : /// If the search fails, they then search for a factory method for
443 : : /// the given type ignoring the class, in case a RRClass independent
444 : : /// factory method is registered.
445 : : /// If it still fails, these methods assume the RDATA is of an "unknown"
446 : : /// type, and creates a new object by calling a constructor of the
447 : : /// \c rdata::generic::Generic class.
448 : : ///
449 : : //@{
450 : : /// \brief Create RDATA of a given pair of RR type and class from a string.
451 : : ///
452 : : /// This method creates from a string an \c Rdata object of the given pair
453 : : /// of RR type and class.
454 : : ///
455 : : /// \param rrtype An \c RRType object specifying the type/class pair.
456 : : /// \param rrclass An \c RRClass object specifying the type/class pair.
457 : : /// \param rdata_string A string of textual representation of the \c Rdata.
458 : : /// \return An \c rdata::RdataPtr object pointing to the created \c Rdata
459 : : /// object.
460 : : rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
461 : : const std::string& rdata_string);
462 : : /// \brief Create RDATA of a given pair of RR type and class from
463 : : /// wire-format data.
464 : : ///
465 : : /// This method creates from wire-format binary data an \c Rdata object
466 : : /// of the given pair of RR type and class.
467 : : ///
468 : : /// \param rrtype An \c RRType object specifying the type/class pair.
469 : : /// \param rrclass An \c RRClass object specifying the type/class pair.
470 : : /// \param buffer A reference to an \c InputBuffer object storing the
471 : : /// \c Rdata to parse.
472 : : /// \param len The length in buffer of the \c Rdata. In bytes.
473 : : /// \return An \c rdata::RdataPtr object pointing to the created \c Rdata
474 : : /// object.
475 : : rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
476 : : isc::util::InputBuffer& buffer, size_t len);
477 : : /// \brief Create RDATA of a given pair of RR type and class, copying
478 : : /// of another RDATA of same kind.
479 : : ///
480 : : /// This method creates an \c Rdata object of the given pair of
481 : : /// RR type and class, copying the content of the given \c Rdata,
482 : : /// \c source.
483 : : ///
484 : : /// \c source must be an object of the concrete derived class of
485 : : /// \c rdata::Rdata for the given pair of RR type and class;
486 : : /// otherwise, an exception of class \c std::bad_cast will be thrown.
487 : : /// In case the \c RRParamRegistry doesn't have a factory method for
488 : : /// the given pair and it is assumed to be of an "unknown" type,
489 : : /// \c source must reference an object of class
490 : : /// \c rdata::generic::Generic; otherwise, an exception of class
491 : : /// \c std::bad_cast will be thrown.
492 : : ///
493 : : /// \param rrtype An \c RRType object specifying the type/class pair.
494 : : /// \param rrclass An \c RRClass object specifying the type/class pair.
495 : : /// \param source A reference to an \c rdata::Rdata object whose content
496 : : /// is to be copied to the created \c rdata::Rdata object.
497 : : /// \return An \c rdata::RdataPtr object pointing to the created
498 : : /// \c rdata::Rdata object.
499 : : rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
500 : : const rdata::Rdata& source);
501 : : //@}
502 : :
503 : : private:
504 : : RRParamRegistryImpl* impl_;
505 : : };
506 : :
507 : : }
508 : : }
509 : : #endif // __RRPARAMREGISTRY_H
510 : :
511 : : // Local Variables:
512 : : // mode: c++
513 : : // End:
|