Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

How to new LookupClient with old LookupClientOptions? #72

Closed
rmbolger opened this issue May 11, 2020 · 10 comments
Closed

How to new LookupClient with old LookupClientOptions? #72

rmbolger opened this issue May 11, 2020 · 10 comments

Comments

@rmbolger
Copy link

rmbolger commented May 11, 2020

I'm fairly new to the library, but liking it a lot so far. Thanks for the effort in maintaining it!

I'm currently playing with it directly from PowerShell and trying to figure out if there's a way to create a new instance of LookupClient with different nameservers, but copy the settings from my old instance. I'm trying to avoid having to create an empty LookupClientOptions and then copy the values to it individually from the old instance's settings.

Something like a LookupClientOptions constructor that takes a LookupClientSettings object....or maybe a static method like LookupClientOptions.FromSettings(). Is there something obvious I'm missing?

P.S. I know about the QueryServer* methods for one-off queries against other nameservers. This would be for a more long term change.

@MichaCo
Copy link
Owner

MichaCo commented May 11, 2020

Creating an oiptions instance from settings doesn't exist because you can just keep an instance of LookupClientOptions which your code handles and updates. And then, every time you change the options, you also have to create a new instance of LookupClient with those options.

That should work in your case too maybe? Instead of using the readonly settings of the client instance, just keep an options variable somewhere?

Just out of curiosity, what are you doing with it in powershell? ;)

@rmbolger
Copy link
Author

rmbolger commented May 11, 2020

Hah, yes. That would be the obvious thing I was missing. Thanks!

Just out of curiosity, what are you doing with it in powershell? ;)

Got tired of waiting for MS to add a decent cross platform DNS module. So toying with making my own using DnsClient.NET so I can stop having to parse dig/nslookup output for every one-off DNS thing I need to do that's more complicated than resolving an IP from a hostname.

@rmbolger
Copy link
Author

rmbolger commented May 11, 2020

Wait no, I think I'm still missing something.

LookupClientOptions.NameServers is read-only. And LookupClient doesn't seem to have a constructor that takes a LookupClientOptions instance and a separate set of nameservers. So if I want to keep the existing options, I'm also stuck with the current nameserver list, no?

In my head, the use experience I'm going for is something like this. When the module loads initially, a LookupClient is spun up with default settings and the system's nameserver list. There's a main function like Resolve-Dns that you can use with or without an explicit nameserver list. For example:

Resolve-Dns example.com CAA
Resolve-Dns example.com CAA -NameServer 8.8.8.8

No problem so far. We can just use QueryServer instead of Query any time they specify explicit nameservers. However, there will also be a function to tweak the LookupClient settings such as Set-DnsClientSetting which would have options to tweak the various settings and the default nameserver list.

# module loads with default settings using system nameservers

# user turns off recursion and makes queries
Set-DnsClientSetting -Recursion:$false
Resolve-Dns example.com CAA

# user changes default nameservers and makes additional queries
# with same client options as before
Set-DnsClientSetting -NameServer 8.8.8.8
Resolve-Dns example.com CAA

# user switches back to default nameservers
Set-DnsClientSetting -UseDefaultNameserver

I suppose I could just keep a copy of the active nameserver list around and just use that via QueryServer unless an explicit list was specified in the function call. But for some reason that feels wrong.

@rmbolger rmbolger reopened this May 11, 2020
@MichaCo
Copy link
Owner

MichaCo commented May 11, 2020

Ah, yeah right, forgot about that ^^

The reason for making the name servers readonly is relatively stupid. Maybe we should make it writeable. Options are supposed to be writeable.

The list of servers is readonly because of the server auto discovery flag.
I didn't want to have the user have to set that to false if they'd add servers after instantiating the options object. That flag is then used later on by the client to determine if it should use the system's DNS servers.

I suppose I could just keep a copy of the active nameserver list around and just use that via QueryServer unless an explicit list was specified in the function call. But for some reason that feels wrong.

That would probably work, yup, but I also agree that it is not perfect ^^

@rmbolger
Copy link
Author

rmbolger commented May 11, 2020

I figured it might have been related to having the cache tied to the current nameservers. And so being able to change them would/should invalidate that cache if it exists.

@MichaCo
Copy link
Owner

MichaCo commented May 11, 2020

Cache is not bound to the source nameserver(s) (anymore). So that shouldn't be an issue

@rmbolger
Copy link
Author

In any case, yes. Having nameservers settable on the options object would definitely solve my problem.

@TropicalThunder
Copy link

TropicalThunder commented May 13, 2020

You can do something like this

private static readonly IPAddress[] _servers = new[]
        {
            IPAddress.Parse("1.1.1.1"),
            IPAddress.Parse("1.0.0.1"),
        };
        private readonly LookupClient _client;

        public DnsLookupService()
        {
            var options = new LookupClientOptions(_servers)
            {
                UseCache = false,
                ThrowDnsErrors = true,
                UseRandomNameServer = false
            };

            _client = new LookupClient(options);
        }

@rmbolger
Copy link
Author

I also just realized that not all of the LookupClient settings are settable directly on an existing instance and the ones that are settable are marked as obsolete. So it seems like the intention is for LookupClient to be immutable once instantiated.

The way I'm currently handling things in order to future proof myself is to keep an instance of LookupClientOptions with the default nameservers which is used to create a fresh LookupClient anytime someone changes a setting. There's also an "active" nameservers list which gets used via QueryServer* methods.

The only minor downside (or feature depending on perspective) is that changing any setting empties the cache since a new LookupClient instance is created. But I'm also disabling cache by default, to make things work more like dig/nslookup. So it shouldn't affect too many people.

@rmbolger
Copy link
Author

@MichaCo I've got a basic v1 version of the module released now. Thanks again for the library and the help.

https://github.com/rmbolger/DnsClient-PS

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants