You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My use case :
I would like to build kind of filter based on tlds.
To do that, I ve build my own resolver that is responding defer.fail(error.DomainError()), when the domain is allowed (the defer.fail will send the query to the next resolver, thanks to the resolverChain ) or defer.fail(dns.AuthoritativeDomainError(query.name.name)) that will send a final NXDOMAIN to the client and will block the domain.
This part work well.
Now, I want to "adapt" my filter regarding devices of my network. For example, if the ip is 192.168.0.4 (the one of my child of 10 years), i want to block youtube from 8pm to ... 8 Am (for example), but i would like that on other devices (192.168.0.50) to be able to go on youtube all the time i want to.
So the solution was to get the ip address of the client. To do that :
class DNSServerFactory2(server.DNSServerFactory):
def handleQuery(self, message, protocol, address):
query = message.queries[0]
# Here, i am just adding a "custom" param on the query to be able to use it in my resolver in the def query of Hector()/Archify()
query.address = address
return (
self.resolver.query(query) # Here i am calling ResolverChain.query()
.addCallback(self.gotResolverResponse, protocol, message, address)
.addErrback(self.gotResolverError, protocol, message, address)
)
But, ...that doesnt work...
When i am printing the query in the DnsServerFactory2 I get something like
So I ve lost the address param during the transfer from the factory to my resolever.
After trying to understand what i am doing wrong, i finnaly found the issue/need to refact.
The current solution :
Same (quiet the same) as before :
class DNSServerFactory2(server.DNSServerFactory):
def __init__(self, authorities=None, caches=None, clients=None, verbose=0):
super().__init__(authorities, caches, clients, verbose)
resolvers = []
if authorities is not None:
resolvers.extend(authorities)
if caches is not None:
resolvers.extend(caches)
if clients is not None:
resolvers.extend(clients)
self.resolver = ResolverChain2(resolvers) # Here the ResolverChain2 !
def handleQuery(self, message, protocol, address): # Same as before
query = message.queries[0]
query.address = address
return (
self.resolver.query(query) # Here, self.resolver is the resolverChain
.addCallback(self.gotResolverResponse, protocol, message, address)
.addErrback(self.gotResolverError, protocol, message, address)
)
The issue ResolverChain vs ResolverChain2
Original :
def _lookup(self, name, cls, type, timeout): #Here the query is "splited" with the params
if not self.resolvers:
return defer.fail(error.DomainError())
q = dns.Query(name, type, cls) # /!\/!\/!\ THIS IS THE REASON OF RE-CREATING THE QUERY /!\/!\/!\
d = self.resolvers[0].query(q, timeout)
for r in self.resolvers[1:]:
d = d.addErrback(FailureHandler(r.query, q, timeout))
return d
def query(self, query, timeout=None):
try:
method = self.typeToMethod[query.type]
except KeyError:
self._log.debug(
"Query of unknown type {query.type} for {query.name.name!r}",
query=query,
)
return defer.maybeDeferred(
self._lookup, query.name.name, dns.IN, query.type, timeout
)
else:
return defer.maybeDeferred(method, query.name.name, timeout)
ResolverChain2
class ResolverChain2(resolve.ResolverChain):
def query(self, query, timeout=None):
# here, i am not sending a new query or something else, just transmitting the original query nothing else
return defer.maybeDeferred(self._lookupbyquery, query, timeout)
def _lookupbyquery(self, query, timeout=None):
if not self.resolvers:
return defer.fail(error.DomainError())
# Same behavior than in the original version, except that i didnt create a new query, i am using the original one with the address param.
d = self.resolvers[0].query(query, timeout)
for r in self.resolvers[1:]:
d = d.addErrback(client.resolve.FailureHandler(r.query, query, timeout))
return d
Finaly :
I think the main problem is that the query is not sended/consumed by the resolver directly.
At the resolver chain level, it needs to consume the query directly, without doing anything on it. Just serve the original query...
Hi,
My use case :
I would like to build kind of filter based on tlds.
To do that, I ve build my own resolver that is responding defer.fail(error.DomainError()), when the domain is allowed (the defer.fail will send the query to the next resolver, thanks to the resolverChain ) or defer.fail(dns.AuthoritativeDomainError(query.name.name)) that will send a final NXDOMAIN to the client and will block the domain.
This part work well.
Now, I want to "adapt" my filter regarding devices of my network. For example, if the ip is 192.168.0.4 (the one of my child of 10 years), i want to block youtube from 8pm to ... 8 Am (for example), but i would like that on other devices (192.168.0.50) to be able to go on youtube all the time i want to.
So the solution was to get the ip address of the client. To do that :
The solution it should works(but it doesnt) :
But, ...that doesnt work...
When i am printing the query in the DnsServerFactory2 I get something like
That is good.
But, if i am doing the same in the custom resolvers, i get that :
So I ve lost the address param during the transfer from the factory to my resolever.
After trying to understand what i am doing wrong, i finnaly found the issue/need to refact.
The current solution :
Same (quiet the same) as before :
The issue ResolverChain vs ResolverChain2
Original :
ResolverChain2
Finaly :
I think the main problem is that the query is not sended/consumed by the resolver directly.
At the resolver chain level, it needs to consume the query directly, without doing anything on it. Just serve the original query...
What do you think about that?
Hope it's clear...
Cheers
Benoît
Searchable metadata
The text was updated successfully, but these errors were encountered: