Stefano Bagnara wrote:
Hi Rob,
this is a great report! I think it will be very useful when we'll define
our goals and how to proceed.
I agree on almost all of your concern. Let's track down some
incompatibility between your view and other's people opinions I read in
this DNS thread.
I agree this is a great insight into some things we might want to
address in our own package and gives a great start for additional
refactorings we may want to perform on dnsjava. I think it's great that
Rob has started his own library, but I don't think the work that has
gone into dnsjava is unusable. I would still prefer to start with
dnsjava and refactor. But some of the insights Rob has given us into
dnsjava are invaluable, such as the records behaving differently
depending on if they've been built/marshalled/unmarshalled. That's
definitely not something one would expect. I also agree on the OO
design issues especially regarding the header and other possible areas
of inconsistency.
Java 5: is this a big requirement for you? Personally I have no big
requirement for platform and I would be fine with a java5+ library, but
I think many users out there have 1.4 compatibility as a requirement.
For me, there is no requirement on Java 5. I believe MINA 2.0 will have
a requirement on Java 5, so I don't see why we wouldn't take advantage
of the latest and greatest available in it.
Record mutability: how often do you need this? Have you compared real
performace tradeoff between mutable records and "immutable
records+clone" approach? I think that when the records are used by
multiple threads then immutability have a great impact on performance.
(e.g: if you return an immutable object from the cache then the user can
read it and do whatever he wants, otherwise you cannot ever return to
the user a record from the cache)
I definitely agree with Stefano here. I don't think
messages/records/etc. should be modified once they have been created.
It should be simple enough to create clone methods that allow you to
modify certain parameters during the clone operation. Then the only
issue would be the performance impact of copying the whole message,
especially if it contains many records. But modifying a message should
be a much more infrequent operation than reading it, so I think the
added benefits outweigh the performance drawback.
Thank you,
Stefano
PS: it would be really cool to have a "preview" of your code, even if it
is far from be complete.
Rob Butler ha scritto:
Having worked with dnsjava, I felt there were some significant issues with it
for the types of applications I wanted to develop.
Specifically,
* I want mutable objects, that can be selectively made immutable.
- dnsjava records are always immutable.
* I want my objects to always work the same no matter if a message has been
"built"/marshaled/unmarshaled.
- some methods, specifically on the Message object behave differently if
you are working with a message that has been parsed from the wire VS one your
are building programatically. For example, if you call Message.setTsig(..) and
later call Message.getTsig() you would expect to get back the TSIG you set
previously. With dnsjava you only get a TSIG back from getTsig() if the
message was parsed from the wire.
* I want all overloaded messages to behave similarly, as a Java coder would
expect.
- Message.toWire() and Message.toWire(int) in dnsjava have some differences
in how they behave. For example, if you had called Message.setTsig(..) you
would expect the TSIG to be written in the DNS message when calling .toWire()
or .toWire(int). The TSIG is only written when .toWire(int) is called.
* I wanted a better OO design and I wanted to use Java 5 language features.
- a DNS Header as a separate object doesn't really make a lot of sense to
me. It only has worth as part of a message. It should at best be an inner
class that is not directly exposed as an object outside of Message, if such a
class even exits. All operations that are in dnsjava's Header should be on a
Message object.
- Because Header is a separate object from Message, it is possible for
strange things to happen in dnsjava. For example, your header could say there
are 2 records in the answer section, even though there are none or vice versa.
- There are response codes for messages, TSIGRecords, and a few other
record types. Even though the response code for NOERROR is always the same
value, the various response codes should probably be inner enums of the
appropriate object types. It wouldn't make sense to specify an NXDOMAIN
response code for a TSIGRecord, but with dnsjava you can.
- Data class only makes sense on records. There should probably be an
inner enum on Record that defines what they are instead of it being a separate
class.
- dnsjava doesn't track some data that it should. For example, if you
parse a message off the wire, you should be able to do something like
TSIG.verify(incomingMessage), because the incomingMessage should know what the
bytes were on the wire. dnsJava doesn't keep track of the original bytes, so
you have to. Because of details I won't get into it's necessary to track the
original message bytes for TSIG validation. You cannot simply re-construct the
byte stream by calling Message.toWire().
* I wanted more separation between a DNS parsing library and things built with
it.
- For example, dnsjava includes a resolver and a minimal DNS server along
with all of the parsing code. It's great this is supplied as part of the
project, but they should be separate modules (jars) within the project. If
your building a DNS server using dnsjava there is no reason to have dnsjava's
server and resolver present. It's not a big deal that they are, but i feel
they should be separate.
- I wanted the parsing library as separate from the IO implementation as
possible.
* I wanted a better exception hierarchy that would allow a developer to know
exactly what went wrong instead of just a single exception for all errors.
* I wanted support for evolving standards like NSEC3, IDN, etc.
* I wanted to do everything possible to make it as fast as possible w/o trading
off good design.
* I wanted everything fully javadoc'd.
Considering all the above, and more, I thought starting from scratch would be the best
approach. I don't want this to sound like a dnsjava bash fest though. Brian's done some
great work developing dnsjava and making it open source. I've learned a lot from using
it and reviewing it's code. I'd just like to develop something with a better "Java
feel". Consider it dnsjava 2.0.
Rob