-
Notifications
You must be signed in to change notification settings - Fork 247
Unnecessary synchronization in org.xbill.DNS.Header::getID #215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
An If you open a PR, you may want to create it against the release/3.4.x branch as master won't get a new release soon. |
I was suggesting using an
That would be the best option IMHO. But but then we lose the lazy initialization of the ID field, which looks like the intention of the author of that class. Using |
Ah, I see.
The default implementation of SecureRandom is SHA1PRNG, which AFAIK doesn't do reseeds and thus will never run out of entropy. I wouldn't know when an unset ID would be useful. Answers coming from the network have an ID which is parsed, and sending request need an ID anyway. The only case where the ID must be statically |
The reason for the lazy initialization, as far as I remember, was to avoid needing to generate a random ID that would immediately be overridden when parsing a header from wire format. It's possible that this is no longer needed; there is an alternate constructor that specifies the ID, and it's used when constructing a header from wire format (which is likely the common case; I'm not sure if there's any other code that separates the construction and parsing). (and for the record, DoH doesn't require an ID of 0, it's a SHOULD. It's also not because of ordered delivery, it's because |
@ibauersachs SHA1PRNG is the default only in windows (see https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SecureRandomImp). On Linux, a slower default implementation is used. Still, if we can agree that the ID has to be set in the constructor either via a parameter or using |
Header::getID synchronized on a static field causing unnecessary locking especially when the ID field didn't need to be generated. As per the discussion in dnsjava#215, this was due to a desire to have the ID generation be lazy, which is no longer needed. This commit changes the ID generation behavior so the ID is either explicitly supplied to the constructor, or generated by the constructor using the same SecureRandom instance. This makes the getID method a simple getter with no need for synchronization
Yes, you're right, I forgot about the DoH http-based caching. I don't have the project open ATM to search for references, but if parsing the message creates an empty Header instance, we should change that. But I assume that's already the case. If the SecureRandom performance really turns out to be an issue I think we can revisit that later. |
It is. I took a glance at the parsing code before submitting the PR. The |
* removed synchronization in Header::getID Header::getID synchronized on a static field causing unnecessary locking especially when the ID field didn't need to be generated. As per the discussion in #215, this was due to a desire to have the ID generation be lazy, which is no longer needed. This commit changes the ID generation behavior so the ID is either explicitly supplied to the constructor, or generated by the constructor using the same SecureRandom instance. This makes the getID method a simple getter with no need for synchronization * Header constructor - check that ID is in range * fixed formatting
I'm working on improving the performance of a project that deals with enormous amounts of dns messages. One of the performance bottlenecks I'm seeing is a whole lot of locking in
org.xbill.DNS.Header::getID
which is implemented like this:The implementation is not only synchronized - it's synchronized around a
static
object, meaning that allgetID
calls in allHeader
instances are serial! Note thatSecureRandom
itself is thread-safe and doesn't require locking.Could the
getID
implementation be changed to be lock-free using avolatile
variable or anAtomicInteger
? Or at least switched to use per-instance locking (e.g. synchronize onthis
or some other non-null field) to reduce the lock's scope?I'd be happy to submit a PR with a lock-free implementation.
The text was updated successfully, but these errors were encountered: