Linux webserver 6.8.0-49-generic #49~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Nov 6 17:42:15 UTC 2 x86_64
Apache/2.4.52 (Ubuntu)
Server IP : 192.168.1.1 & Your IP : 3.14.7.99
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
snap /
lxd /
31333 /
share /
openvswitch /
python /
ovs /
Delete
Unzip
Name
Size
Permission
Date
Action
compat
[ DIR ]
drwxr-xr-x
2024-11-20 14:23
db
[ DIR ]
drwxr-xr-x
2024-11-20 14:23
flow
[ DIR ]
drwxr-xr-x
2024-11-20 14:23
unixctl
[ DIR ]
drwxr-xr-x
2024-11-20 14:23
__init__.py
38
B
-rw-r--r--
2024-11-20 14:02
daemon.py
20.22
KB
-rw-r--r--
2024-11-20 14:02
dirs.py
1.29
KB
-rw-r--r--
2024-11-20 14:02
dns_resolve.py
9.51
KB
-rw-r--r--
2024-11-20 14:02
fatal_signal.py
4.65
KB
-rw-r--r--
2024-11-20 14:02
fcntl_win.py
1.3
KB
-rw-r--r--
2024-11-20 14:02
json.py
16.45
KB
-rw-r--r--
2024-11-20 14:02
jsonrpc.py
20.6
KB
-rw-r--r--
2024-11-20 14:02
ovsuuid.py
1.83
KB
-rw-r--r--
2024-11-20 14:02
poller.py
10.04
KB
-rw-r--r--
2024-11-20 14:02
process.py
1.43
KB
-rw-r--r--
2024-11-20 14:02
reconnect.py
25.4
KB
-rw-r--r--
2024-11-20 14:02
socket_util.py
12.19
KB
-rw-r--r--
2024-11-20 14:02
stream.py
31.43
KB
-rw-r--r--
2024-11-20 14:02
timeval.py
2.38
KB
-rw-r--r--
2024-11-20 14:02
util.py
3.05
KB
-rw-r--r--
2024-11-20 14:02
version.py
93
B
-rw-r--r--
2024-11-20 14:02
vlog.py
16.3
KB
-rw-r--r--
2024-11-20 14:02
winutils.py
9.01
KB
-rw-r--r--
2024-11-20 14:02
Save
Rename
# Copyright (c) 2023 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import collections import enum import functools import ipaddress import os import time import typing try: import unbound # type: ignore except ImportError: pass import ovs.vlog vlog = ovs.vlog.Vlog("dns_resolve") class ReqState(enum.Enum): INVALID = 0 PENDING = 1 GOOD = 2 ERROR = 3 class DNSRequest: def __init__(self, name: str): self.name: str = name self.state: ReqState = ReqState.INVALID self.time: typing.Optional[float] = None # set by DNSResolver._callback self.result: typing.Optional[str] = None self.ttl: typing.Optional[float] = None @property def expired(self): return time.time() > self.time + self.ttl @property def is_valid(self): return self.state == ReqState.GOOD and not self.expired def __str__(self): return (f"DNSRequest(name={self.name}, state={self.state}, " f"time={self.time}, result={self.result})") class DefaultReqDict(collections.defaultdict): def __init__(self): super().__init__(DNSRequest) def __missing__(self, key): ret = self.default_factory(key) self[key] = ret return ret class UnboundException(Exception): def __init__(self, message, errno): try: msg = f"{message}: {unbound.ub_strerror(errno)}" except NameError: msg = message super().__init__(msg) def dns_enabled(func): @functools.wraps(func) def wrapper(self, *args, **kwargs): if self.dns_enabled: return func(self, *args, **kwargs) vlog.err("DNS support requires the python unbound library") return wrapper class DNSResolver: def __init__(self, is_daemon: bool = False): """Create a resolver instance If is_daemon is true, set the resolver to handle requests asynchronously. The following environment variables are processed: OVS_UNBOUND_CONF: The filename for an unbound.conf file OVS_RESOLV_CONF: A filename to override the system default resolv.conf OVS_HOSTS_FILE: A filename to override the system default hosts file In the event that the unbound library is missing or fails to initialize DNS lookup support will be disabled and the resolve() method will return None. """ self._is_daemon = is_daemon try: self._ctx = unbound.ub_ctx() self.dns_enabled = True except Exception: # The unbound docs mention that this could thrown an exception # but do not specify what exception that is. This can also # happen with a missing unbound library. self.dns_enabled = False vlog.err("Failed to initialize the unbound library") return # NOTE(twilson) This cache, like the C version, can grow without bound # and has no cleanup or aging mechanism. Given our usage patterns, this # should not be a problem. But this should not be used to resolve an # unbounded list of addresses in a long-running daemon. self._requests = DefaultReqDict() self._ub_call(self._set_unbound_conf) # NOTE(twilson) The C version disables DNS in this case. I didn't do # that here since it could still be useful to resolve addresses from # /etc/hosts even w/o resolv.conf self._ub_call(self._set_resolv_conf) self._ub_call(self._set_hosts_file) self._ctx.set_async(True) # Sets threaded behavior for resolve_async() def _ub_call(self, fn, *args, **kwargs): """Convert UnboundExceptions into vlog warnings""" try: return fn(*args, **kwargs) except UnboundException as e: vlog.warn(e) @dns_enabled def _set_unbound_conf(self): ub_cfg = os.getenv("OVS_UNBOUND_CONF") if ub_cfg: retval = self._ctx.config(ub_cfg) if retval != 0: raise UnboundException( "Failed to set libunbound context config", retval) @dns_enabled def _set_resolv_conf(self): filename = os.getenv("OVS_RESOLV_CONF") # The C lib checks that the file exists and also sets filename to # /etc/resolv.conf on non-Windows, but resolvconf already does this. retval = self._ctx.resolvconf(filename) if retval != 0: location = filename or "system default nameserver" raise UnboundException(location, retval) @dns_enabled def _set_hosts_file(self): # The C lib doesn't have the ability to set a hosts file, but it is # useful to have, especially for writing tests that don't rely on # network connectivity. hosts(None) uses /etc/hosts. filename = os.getenv("OVS_HOSTS_FILE") retval = self._ctx.hosts(filename) if retval != 0: location = filename or "system default hosts file" raise UnboundException(location, retval) @dns_enabled def _callback(self, req: DNSRequest, err: int, result): if err != 0 or (result.qtype == unbound.RR_TYPE_AAAA and not result.havedata): req.state = ReqState.ERROR vlog.warn(f"{req.name}: failed to resolve") return if result.qtype == unbound.RR_TYPE_A and not result.havedata: self._resolve_async(req, unbound.RR_TYPE_AAAA) return try: ip_str = next(iter(result.data.as_raw_data())) ip = ipaddress.ip_address(ip_str) # test if IP is valid # NOTE (twilson) For some reason, accessing result data outside of # _callback causes a segfault. So just grab and store what we need. req.result = str(ip) req.ttl = result.ttl req.state = ReqState.GOOD req.time = time.time() except (ValueError, StopIteration): req.state = ReqState.ERROR vlog.err(f"{req.name}: failed to resolve") @dns_enabled def _resolve_sync(self, name: str) -> typing.Optional[str]: for qtype in (unbound.RR_TYPE_A, unbound.RR_TYPE_AAAA): err, result = self._ctx.resolve(name, qtype) if err != 0: return None if not result.havedata: continue try: ip = ipaddress.ip_address( next(iter(result.data.as_raw_data()))) except (ValueError, StopIteration): return None return str(ip) return None @dns_enabled def _resolve_async(self, req: DNSRequest, qtype) -> None: err, _ = self._ctx.resolve_async(req.name, req, self._callback, qtype) if err != 0: req.state = ReqState.ERROR return None req.state = ReqState.PENDING return None @dns_enabled def resolve(self, name: str) -> typing.Optional[str]: """Resolve a host name to an IP address If the resolver is set to handle requests asynchronously, resolve() should be recalled until it returns a non-None result. Errors will be logged. :param name: The host name to resolve :returns: The IP address or None on error or not (yet) found """ if not self._is_daemon: return self._resolve_sync(name) retval = self._ctx.process() if retval != 0: vlog.err(f"dns-resolve error: {unbound.ub_strerror(retval)}") return None req = self._requests[name] # Creates a DNSRequest if not found if req.is_valid: return req.result elif req.state != ReqState.PENDING: self._resolve_async(req, unbound.RR_TYPE_A) return None _global_resolver: typing.Optional[DNSResolver] = None def init(is_daemon: bool = False) -> DNSResolver: """Initialize a global DNSResolver See DNSResolver.__init__ for more details """ global _global_resolver _global_resolver = DNSResolver(is_daemon) return _global_resolver def resolve(name: str) -> typing.Optional[str]: """Resolve a host name to an IP address If a DNSResolver instance has not been instantiated, or if it has been created with is_daemon=False, resolve() will synchronously resolve the hostname. If DNSResolver has been initialized with is_daemon=True, it will instead resolve asynchornously and resolve() will return None until the hostname has been resolved. :param name: The host name to resolve :returns: The IP address or None on error or not (yet) found """ if _global_resolver is None: init() # mypy doesn't understand that init() sets _global_resolver, so ignore type return _global_resolver.resolve(name) # type: ignore def destroy(): """Destroy the global DNSResolver This destroys the global DNSResolver instance and any outstanding asynchronouse requests. """ global _global_resolver del _global_resolver _global_resolver = None # noqa: F841