Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
3a81d2d9
Commit
3a81d2d9
authored
Dec 03, 2012
by
Michal 'vorner' Vaner
Browse files
Merge remote-tracking branch 'origin/trac2382' into base/loader
parents
425e18f7
5d239b6a
Changes
42
Hide whitespace changes
Inline
Side-by-side
src/lib/dns/Makefile.am
View file @
3a81d2d9
...
...
@@ -120,6 +120,7 @@ libb10_dns___la_SOURCES += tsigkey.h tsigkey.cc
libb10_dns___la_SOURCES
+=
tsigrecord.h tsigrecord.cc
libb10_dns___la_SOURCES
+=
character_string.h character_string.cc
libb10_dns___la_SOURCES
+=
master_loader_callbacks.h
libb10_dns___la_SOURCES
+=
master_loader.h
libb10_dns___la_SOURCES
+=
rdata/generic/detail/nsec_bitmap.h
libb10_dns___la_SOURCES
+=
rdata/generic/detail/nsec_bitmap.cc
libb10_dns___la_SOURCES
+=
rdata/generic/detail/nsec3param_common.cc
...
...
src/lib/dns/gen-rdatacode.py.in
View file @
3a81d2d9
...
...
@@ -28,6 +28,7 @@ re_typecode = re.compile('([\da-z]+)_(\d+)')
classcode2txt = {}
typecode2txt = {}
typeandclass = []
new_rdatafactory_users = ['aaaa']
generic_code = 65536 # something larger than any code value
rdata_declarations = ''
class_definitions = ''
...
...
@@ -116,6 +117,9 @@ class AbstractMessageRenderer;\n\n'''
explicit ''' + type_utxt + '''(const std::string& type_str);
''' + type_utxt + '''(isc::util::InputBuffer& buffer, size_t rdata_len);
''' + type_utxt + '''(const ''' + type_utxt + '''& other);
''' + type_utxt + '''(
MasterLexer& lexer, const Name* name,
MasterLoader::Options options, MasterLoaderCallbacks& callbacks);
virtual std::string toText() const;
virtual void toWire(isc::util::OutputBuffer& buffer) const;
virtual void toWire(AbstractMessageRenderer& renderer) const;
...
...
@@ -203,17 +207,33 @@ def generate_rdatadef(file, basemtime):
rdata_deffile.write(class_definitions)
rdata_deffile.close()
def generate_rdatahdr(file, declarations, basemtime):
def generate_rdatahdr(file,
heading,
declarations, basemtime):
if not need_generate(file, basemtime):
print('skip generating ' + file);
return
heading += '''
#ifndef DNS_RDATACLASS_H
#define DNS_RDATACLASS_H 1
#include <dns/master_loader.h>
namespace isc {
namespace dns {
class Name;
class MasterLexer;
class MasterLoaderCallbacks;
}
}
'''
declarations += '''
#endif // DNS_RDATACLASS_H
// Local Variables:
// mode: c++
// End:
'''
rdata_header = open(file, 'w')
rdata_header.write(heading
_txt
)
rdata_header.write(heading)
rdata_header.write(declarations)
rdata_header.close()
...
...
@@ -271,15 +291,24 @@ def generate_rrparam(fileprefix, basemtime):
class_utxt = class_tuple[1].upper()
indent = ' ' * 8
typeandclassparams += indent
# By default, we use OldRdataFactory (see bug #2497). If you
# want to pick RdataFactory for a particular type, add it to
# new_rdatafactory_users.
if type_txt in new_rdatafactory_users:
rdf_class = 'RdataFactory'
else:
rdf_class = 'OldRdataFactory'
if class_tuple[1] != 'generic':
typeandclassparams += 'add("' + type_utxt + '", '
typeandclassparams += str(type_code) + ', "' + class_utxt
typeandclassparams += '", ' + str(class_code)
typeandclassparams += ', RdataFactoryPtr(new
RdataFactory
<'
typeandclassparams += ', RdataFactoryPtr(new
' + rdf_class + '
<'
typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
else:
typeandclassparams += 'add("' + type_utxt + '", ' + str(type_code)
typeandclassparams += ', RdataFactoryPtr(new
RdataFactory
<'
typeandclassparams += ', RdataFactoryPtr(new
' + rdf_class + '
<'
typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
rrparam_temp = open(placeholder, 'r')
...
...
@@ -296,8 +325,8 @@ if __name__ == "__main__":
try:
import_definitions(classcode2txt, typecode2txt, typeandclass)
generate_rdatadef('@builddir@/rdataclass.cc', rdatadef_mtime)
generate_rdatahdr('@builddir@/rdataclass.h',
rdata_declarations
,
rdatahdr_mtime)
generate_rdatahdr('@builddir@/rdataclass.h',
heading_txt
,
rdata_declarations,
rdatahdr_mtime)
generate_typeclasscode('rrtype', rdatahdr_mtime, typecode2txt, 'Type')
generate_typeclasscode('rrclass', classdir_mtime,
classcode2txt, 'Class')
...
...
src/lib/dns/master_lexer.cc
View file @
3a81d2d9
...
...
@@ -458,8 +458,11 @@ String::handle(MasterLexer& lexer) const {
if
(
getLexerImpl
(
lexer
)
->
isTokenEnd
(
c
,
escaped
))
{
getLexerImpl
(
lexer
)
->
source_
->
ungetChar
();
// make sure it nul-terminated as a c-str (excluded from token
// data).
data
.
push_back
(
'\0'
);
getLexerImpl
(
lexer
)
->
token_
=
MasterToken
(
&
data
.
at
(
0
),
data
.
size
());
MasterToken
(
&
data
.
at
(
0
),
data
.
size
()
-
1
);
return
;
}
escaped
=
(
c
==
'\\'
&&
!
escaped
);
...
...
@@ -486,7 +489,10 @@ QString::handle(MasterLexer& lexer) const {
escaped
=
false
;
data
.
back
()
=
'"'
;
}
else
{
token
=
MasterToken
(
&
data
.
at
(
0
),
data
.
size
(),
true
);
// make sure it nul-terminated as a c-str (excluded from token
// data). This also simplifies the case of an empty string.
data
.
push_back
(
'\0'
);
token
=
MasterToken
(
&
data
.
at
(
0
),
data
.
size
()
-
1
,
true
);
return
;
}
}
else
if
(
c
==
'\n'
&&
!
escaped
)
{
...
...
@@ -529,7 +535,8 @@ Number::handle(MasterLexer& lexer) const {
token
=
MasterToken
(
MasterToken
::
NUMBER_OUT_OF_RANGE
);
}
}
else
{
token
=
MasterToken
(
&
data
.
at
(
0
),
data
.
size
());
data
.
push_back
(
'\0'
);
// see String::handle()
token
=
MasterToken
(
&
data
.
at
(
0
),
data
.
size
()
-
1
);
}
return
;
}
...
...
src/lib/dns/master_lexer.h
View file @
3a81d2d9
...
...
@@ -90,6 +90,13 @@ public:
/// the region. On the other hand, it is not ensured that the string
/// is nul-terminated. So the usual string manipulation API may not work
/// as expected.
///
/// The `MasterLexer` implementation ensures that there are at least
/// len + 1 bytes of valid memory region starting from beg, and that
/// beg[len] is \0. This means the application can use the bytes as a
/// validly nul-terminated C string if there is no intermediate nul
/// character. Note also that due to this property beg is always non
/// NULL; for an empty string len will be set to 0 and beg[0] is \0.
struct
StringRegion
{
const
char
*
beg
;
///< The start address of the string
size_t
len
;
///< The length of the string in bytes
...
...
src/lib/dns/master_loader.h
0 → 100644
View file @
3a81d2d9
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// 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 MASTER_LOADER_H
#define MASTER_LOADER_H
namespace
isc
{
namespace
dns
{
// Placeholder introduced by #2497. The real class should be updated in
// #2377.
class
MasterLoader
{
public:
enum
Options
{
MANY_ERRORS
,
// lenient mode
// also eventually some check policies like "check NS name"
};
};
}
}
#endif // MASTER_LOADER_H
src/lib/dns/master_loader_callbacks.h
View file @
3a81d2d9
...
...
@@ -119,4 +119,4 @@ private:
}
}
#endif // LOADER_CALLBACKS_H
#endif //
MASTER_
LOADER_CALLBACKS_H
src/lib/dns/rdata.cc
View file @
3a81d2d9
...
...
@@ -30,6 +30,7 @@
#include
<util/buffer.h>
#include
<dns/name.h>
#include
<dns/messagerenderer.h>
#include
<dns/master_lexer.h>
#include
<dns/rdata.h>
#include
<dns/rrparamregistry.h>
#include
<dns/rrtype.h>
...
...
@@ -65,7 +66,7 @@ createRdata(const RRType& rrtype, const RRClass& rrclass,
RdataPtr
rdata
=
RRParamRegistry
::
getRegistry
().
createRdata
(
rrtype
,
rrclass
,
buffer
,
len
);
if
(
buffer
.
getPosition
()
-
old_pos
!=
len
)
{
isc_throw
(
InvalidRdataLength
,
"RDLENGTH mismatch: "
<<
buffer
.
getPosition
()
-
old_pos
<<
" != "
<<
len
);
...
...
@@ -81,6 +82,90 @@ createRdata(const RRType& rrtype, const RRClass& rrclass, const Rdata& source)
source
));
}
namespace
{
void
fromtextError
(
bool
&
error_issued
,
const
MasterLexer
&
lexer
,
MasterLoaderCallbacks
&
callbacks
,
const
MasterToken
*
token
,
const
char
*
reason
)
{
// Don't be too noisy if there are many issues for single RDATA
if
(
error_issued
)
{
return
;
}
error_issued
=
true
;
if
(
token
==
NULL
)
{
callbacks
.
error
(
lexer
.
getSourceName
(),
lexer
.
getSourceLine
(),
"createRdata from text failed: "
+
string
(
reason
));
return
;
}
switch
(
token
->
getType
())
{
case
MasterToken
::
STRING
:
case
MasterToken
::
QSTRING
:
callbacks
.
error
(
lexer
.
getSourceName
(),
lexer
.
getSourceLine
(),
"createRdata from text failed near '"
+
token
->
getString
()
+
"': "
+
string
(
reason
));
break
;
case
MasterToken
::
ERROR
:
callbacks
.
error
(
lexer
.
getSourceName
(),
lexer
.
getSourceLine
(),
"createRdata from text failed: "
+
token
->
getErrorText
());
break
;
default:
assert
(
false
);
}
}
}
RdataPtr
createRdata
(
const
RRType
&
rrtype
,
const
RRClass
&
rrclass
,
MasterLexer
&
lexer
,
const
Name
*
origin
,
MasterLoader
::
Options
options
,
MasterLoaderCallbacks
&
callbacks
)
{
RdataPtr
rdata
;
bool
error_issued
=
false
;
try
{
rdata
=
RRParamRegistry
::
getRegistry
().
createRdata
(
rrtype
,
rrclass
,
lexer
,
origin
,
options
,
callbacks
);
}
catch
(
const
MasterLexer
::
LexerError
&
error
)
{
fromtextError
(
error_issued
,
lexer
,
callbacks
,
&
error
.
token_
,
""
);
}
catch
(
const
Exception
&
ex
)
{
// Catching all isc::Exception is too broad, but right now we don't
// have better granularity. When we complete #2518 we can make this
// finer.
fromtextError
(
error_issued
,
lexer
,
callbacks
,
NULL
,
ex
.
what
());
}
// Other exceptions mean a serious implementation bug or fatal system
// error; it doesn't make sense to catch and try to recover from them
// here. Just propagate.
// Consume to end of line / file.
// Call callback via fromtextError once if there was an error.
do
{
const
MasterToken
&
token
=
lexer
.
getNextToken
();
switch
(
token
.
getType
())
{
case
MasterToken
::
END_OF_LINE
:
return
(
rdata
);
case
MasterToken
::
END_OF_FILE
:
callbacks
.
warning
(
lexer
.
getSourceName
(),
lexer
.
getSourceLine
(),
"file does not end with newline"
);
return
(
rdata
);
default:
rdata
.
reset
();
// we'll return NULL
fromtextError
(
error_issued
,
lexer
,
callbacks
,
&
token
,
"extra input text"
);
// Continue until we see EOL or EOF
}
}
while
(
true
);
// We shouldn't reach here
assert
(
false
);
return
(
RdataPtr
());
// add explicit return to silence some compilers
}
int
compareNames
(
const
Name
&
n1
,
const
Name
&
n2
)
{
size_t
len1
=
n1
.
getLength
();
...
...
@@ -119,7 +204,8 @@ Generic::Generic(isc::util::InputBuffer& buffer, size_t rdata_len) {
impl_
=
new
GenericImpl
(
data
);
}
Generic
::
Generic
(
const
std
::
string
&
rdata_string
)
{
void
Generic
::
constructHelper
(
const
std
::
string
&
rdata_string
)
{
istringstream
iss
(
rdata_string
);
string
unknown_mark
;
iss
>>
unknown_mark
;
...
...
@@ -180,6 +266,34 @@ Generic::Generic(const std::string& rdata_string) {
impl_
=
new
GenericImpl
(
data
);
}
Generic
::
Generic
(
const
std
::
string
&
rdata_string
)
{
constructHelper
(
rdata_string
);
}
Generic
::
Generic
(
MasterLexer
&
lexer
,
const
Name
*
,
MasterLoader
::
Options
,
MasterLoaderCallbacks
&
)
{
std
::
string
s
;
while
(
true
)
{
const
MasterToken
&
token
=
lexer
.
getNextToken
();
if
((
token
.
getType
()
==
MasterToken
::
END_OF_FILE
)
||
(
token
.
getType
()
==
MasterToken
::
END_OF_LINE
))
{
lexer
.
ungetToken
();
// let the upper layer handle the end-of token
break
;
}
if
(
!
s
.
empty
())
{
s
+=
" "
;
}
s
+=
token
.
getString
();
}
constructHelper
(
s
);
}
Generic
::~
Generic
()
{
delete
impl_
;
}
...
...
src/lib/dns/rdata.h
View file @
3a81d2d9
...
...
@@ -15,11 +15,15 @@
#ifndef RDATA_H
#define RDATA_H 1
#include
<stdint.h>
#include
<dns/master_lexer.h>
#include
<dns/master_loader.h>
#include
<dns/master_loader_callbacks.h>
#include
<exceptions/exceptions.h>
#include
<boost/shared_ptr.hpp>
#include
<
exceptions/exceptions
.h>
#include
<
stdint
.h>
namespace
isc
{
namespace
util
{
...
...
@@ -279,6 +283,11 @@ public:
/// \param rdata_len The length in buffer of the \c Rdata. In bytes.
Generic
(
isc
::
util
::
InputBuffer
&
buffer
,
size_t
rdata_len
);
/// \brief Constructor from master lexer.
///
Generic
(
MasterLexer
&
lexer
,
const
Name
*
name
,
MasterLoader
::
Options
options
,
MasterLoaderCallbacks
&
callbacks
);
///
/// \brief The destructor.
virtual
~
Generic
();
...
...
@@ -367,7 +376,10 @@ public:
/// \return > 0 if \c this would be sorted after \c other.
virtual
int
compare
(
const
Rdata
&
other
)
const
;
//@}
private:
void
constructHelper
(
const
std
::
string
&
rdata_string
);
GenericImpl
*
impl_
;
};
...
...
@@ -472,6 +484,53 @@ RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
/// \c Rdata object.
RdataPtr
createRdata
(
const
RRType
&
rrtype
,
const
RRClass
&
rrclass
,
const
Rdata
&
source
);
/// \brief Create RDATA of a given pair of RR type and class using the
/// master lexer.
///
/// This is a more generic form of factory from textual RDATA, and is mainly
/// intended to be used internally by the master file parser (\c MasterLoader)
/// of this library.
///
/// The \c lexer is expected to be at the beginning of textual RDATA of the
/// specified type and class. This function (and its underlying Rdata
/// implementations) extracts necessary tokens from the lexer and constructs
/// the RDATA from them.
///
/// Due to the intended usage of this version, this function handles error
/// cases quite differently from other versions. It internally catches
/// most of syntax and semantics errors of the input (reported as exceptions),
/// calls the corresponding callback specified by the \c callbacks parameters,
/// and returns a NULL smart pointer. If the caller rather wants to get
/// an exception in these cases, it can use pass a callback that internally
/// throws on error. Some critical exceptions such as \c std::bad_alloc are
/// still propagated to the upper layer as it doesn't make sense to try
/// recovery from such a situation within this function.
///
/// Whether or not the creation succeeds, this function updates the lexer
/// until it reaches either the end of line or file, starting from the end of
/// the RDATA text (or the point of failure if the parsing fails in the
/// middle of it). The caller can therefore assume it's ready for reading
/// the next data (which is normally a subsequent RR in the zone file) on
/// return, whether or not this function succeeds.
///
/// \param rrtype An \c RRType object specifying the type/class pair.
/// \param rrclass An \c RRClass object specifying the type/class pair.
/// \param lexer A \c MasterLexer object parsing a master file for the
/// RDATA to be created
/// \param origin If non NULL, specifies the origin of any domain name fields
/// of the RDATA that are non absolute.
/// \param options Master loader options controlling how to deal with errors
/// or non critical issues in the parsed RDATA.
/// \param callbacks Callback to be called when an error or non critical issue
/// is found.
/// \return An \c RdataPtr object pointing to the created
/// \c Rdata object. Will be NULL if parsing fails.
RdataPtr
createRdata
(
const
RRType
&
rrtype
,
const
RRClass
&
rrclass
,
MasterLexer
&
lexer
,
const
Name
*
origin
,
MasterLoader
::
Options
options
,
MasterLoaderCallbacks
&
callbacks
);
//@}
///
...
...
@@ -511,6 +570,6 @@ int compareNames(const Name& n1, const Name& n2);
}
#endif // RDATA_H
// Local Variables:
// Local Variables:
// mode: c++
// End:
// End:
src/lib/dns/rdata/in_1/aaaa_28.cc
View file @
3a81d2d9
...
...
@@ -12,6 +12,15 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
<exceptions/exceptions.h>
#include
<util/buffer.h>
#include
<dns/exceptions.h>
#include
<dns/messagerenderer.h>
#include
<dns/rdata.h>
#include
<dns/rdataclass.h>
#include
<dns/master_lexer.h>
#include
<dns/master_loader.h>
#include
<stdint.h>
#include
<string.h>
...
...
@@ -20,14 +29,6 @@
#include
<arpa/inet.h>
// XXX: for inet_pton/ntop(), not exist in C++ standards
#include
<sys/socket.h>
// for AF_INET/AF_INET6
#include
<exceptions/exceptions.h>
#include
<util/buffer.h>
#include
<dns/exceptions.h>
#include
<dns/messagerenderer.h>
#include
<dns/rdata.h>
#include
<dns/rdataclass.h>
using
namespace
std
;
using
namespace
isc
::
util
;
...
...
@@ -42,6 +43,16 @@ AAAA::AAAA(const std::string& addrstr) {
}
}
AAAA
::
AAAA
(
MasterLexer
&
lexer
,
const
Name
*
,
MasterLoader
::
Options
,
MasterLoaderCallbacks
&
)
{
const
MasterToken
&
token
=
lexer
.
getNextToken
(
MasterToken
::
STRING
);
if
(
inet_pton
(
AF_INET6
,
token
.
getStringRegion
().
beg
,
&
addr_
)
!=
1
)
{
isc_throw
(
InvalidRdataText
,
"Failed to convert '"
<<
token
.
getString
()
<<
"' to IN/AAAA RDATA"
);
}
}
AAAA
::
AAAA
(
InputBuffer
&
buffer
,
size_t
rdata_len
)
{
if
(
rdata_len
!=
sizeof
(
addr_
))
{
isc_throw
(
DNSMessageFORMERR
,
...
...
src/lib/dns/rdata/template.cc
View file @
3a81d2d9
...
...
@@ -34,6 +34,11 @@ using namespace isc::util;
// If you added member functions specific to this derived class, you'll need
// to implement them here, of course.
MyType
::
MyType
(
MasterLexer
&
lexer
,
const
Name
*
origin
,
MasterLoader
::
Options
options
,
MasterLoaderCallbacks
&
callbacks
)
{
}
MyType
::
MyType
(
const
string
&
type_str
)
{
}
...
...
src/lib/dns/rrparamregistry-placeholder.cc
View file @
3a81d2d9
...
...
@@ -37,10 +37,40 @@ using namespace std;
using
namespace
boost
;
using
namespace
isc
::
util
;
using
namespace
isc
::
dns
::
rdata
;
using
namespace
isc
::
dns
::
rdata
;
namespace
isc
{
namespace
dns
{
namespace
rdata
{
RdataPtr
AbstractRdataFactory
::
create
(
MasterLexer
&
lexer
,
const
Name
*
,
MasterLoader
::
Options
,
MasterLoaderCallbacks
&
)
const
{
std
::
string
s
;
while
(
true
)
{
const
MasterToken
&
token
=
lexer
.
getNextToken
();
if
((
token
.
getType
()
==
MasterToken
::
END_OF_FILE
)
||
(
token
.
getType
()
==
MasterToken
::
END_OF_LINE
))
{
lexer
.
ungetToken
();
// let the upper layer handle the end-of token
break
;
}
if
(
!
s
.
empty
())
{
s
+=
" "
;
}
s
+=
token
.
getString
();
}
return
(
create
(
s
));
}
}
// end of namespace isc::dns::rdata
namespace
{
///
/// The following function and class are a helper to define case-insensitive
...
...
@@ -161,8 +191,10 @@ typedef map<RRTypeClass, RdataFactoryPtr> RdataFactoryMap;
typedef
map
<
RRType
,
RdataFactoryPtr
>
GenericRdataFactoryMap
;
template
<
typename
T
>
class
RdataFactory
:
public
AbstractRdataFactory
{
class
Old
RdataFactory
:
public
AbstractRdataFactory
{
public:
using
AbstractRdataFactory
::
create
;
virtual
RdataPtr
create
(
const
string
&
rdata_str
)
const
{
return
(
RdataPtr
(
new
T
(
rdata_str
)));
...
...
@@ -179,6 +211,18 @@ public:
}
};
template
<
typename
T
>
class
RdataFactory
:
public
OldRdataFactory
<
T
>
{
public:
using
OldRdataFactory
<
T
>::
create
;
virtual
RdataPtr
create
(
MasterLexer
&
lexer
,
const
Name
*
origin
,
MasterLoader
::
Options
options
,
MasterLoaderCallbacks
&
callbacks
)
const
{
return
(
RdataPtr
(
new
T
(
lexer
,
origin
,
options
,
callbacks
)));
}
};
///
/// \brief The \c RRParamRegistryImpl class is the actual implementation of
/// \c RRParamRegistry.
...
...
@@ -305,7 +349,7 @@ namespace {
/// This could be simplified using strncasecmp(), but unfortunately it's not
/// included in <cstring>. To be as much as portable within the C++ standard
/// we take the "in house" approach here.
///
///
bool
CICharEqual
(
char
c1
,
char
c2
)
{
return
(
tolower
(
static_cast
<
unsigned
char
>
(
c1
))
==
tolower
(
static_cast
<
unsigned
char
>
(
c2
)));
...
...
@@ -528,5 +572,26 @@ RRParamRegistry::createRdata(const RRType& rrtype, const RRClass& rrclass,
return
(
RdataPtr
(
new
rdata
::
generic
::
Generic
(
dynamic_cast
<
const
generic
::
Generic
&>
(
source
))));
}
RdataPtr
RRParamRegistry
::
createRdata
(
const
RRType
&
rrtype
,
const
RRClass
&
rrclass
,
MasterLexer
&
lexer
,
const
Name
*
name
,
MasterLoader
::
Options
options
,
MasterLoaderCallbacks
&
callbacks
)
{
RdataFactoryMap
::
const_iterator
found
=
impl_
->
rdata_factories
.
find
(
RRTypeClass
(
rrtype
,
rrclass
));
if
(
found
!=
impl_
->
rdata_factories
.
end
())
{
return
(
found
->
second
->
create
(
lexer
,
name
,
options
,
callbacks
));
}
GenericRdataFactoryMap
::
const_iterator
genfound
=
impl_
->
genericrdata_factories
.
find
(
rrtype
);
if
(
genfound
!=
impl_
->
genericrdata_factories
.
end
())
{
return
(
genfound
->
second
->
create
(
lexer
,
name
,
options
,
callbacks
));
}
return
(
RdataPtr
(
new
generic
::
Generic
(
lexer
,
name
,
options
,
callbacks
)));
}
}
}
src/lib/dns/rrparamregistry.h
View file @
3a81d2d9
...
...
@@ -82,7 +82,7 @@ public:
/// \name Factory methods for polymorphic creation.
///
//@{
///
/// \brief Create RDATA from a string.
///
/// This method creates from a string an \c Rdata object of specific class
...
...
@@ -91,7 +91,7 @@ public:
/// \param rdata_str A string of textual representation of the \c Rdata.
/// \return An \c RdataPtr object pointing to the created \c Rdata object.
virtual
RdataPtr
create
(
const
std