feat(gui): add reverse DNS hostname detection for peers
Resolve hostname via PTR record on peer endpoint IP. Results cached in memory for 5 minutes to avoid latency. Hostname shown below endpoint in the peers table. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+23
@@ -197,6 +197,27 @@ def humanize_ago(ts: int, now: int) -> str:
|
|||||||
return f"{diff // 86400}д назад"
|
return f"{diff // 86400}д назад"
|
||||||
|
|
||||||
|
|
||||||
|
_dns_cache: dict = {} # ip -> (hostname, expires_ts)
|
||||||
|
_DNS_TTL = 300 # 5 минут
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_hostname(ip: str) -> str:
|
||||||
|
if not ip or ip in ("-", "(none)"):
|
||||||
|
return ""
|
||||||
|
now = time.time()
|
||||||
|
if ip in _dns_cache:
|
||||||
|
host, exp = _dns_cache[ip]
|
||||||
|
if now < exp:
|
||||||
|
return host
|
||||||
|
import socket
|
||||||
|
try:
|
||||||
|
host = socket.gethostbyaddr(ip)[0]
|
||||||
|
except Exception:
|
||||||
|
host = ""
|
||||||
|
_dns_cache[ip] = (host, now + _DNS_TTL)
|
||||||
|
return host
|
||||||
|
|
||||||
|
|
||||||
def next_free_ip(network: str) -> str:
|
def next_free_ip(network: str) -> str:
|
||||||
import ipaddress
|
import ipaddress
|
||||||
try:
|
try:
|
||||||
@@ -297,6 +318,7 @@ def index():
|
|||||||
"routes": row.get("advertised_routes") or "-",
|
"routes": row.get("advertised_routes") or "-",
|
||||||
"allowed_ips": rt.get("allowed_ips", "-"),
|
"allowed_ips": rt.get("allowed_ips", "-"),
|
||||||
"endpoint": rt.get("endpoint", "-"),
|
"endpoint": rt.get("endpoint", "-"),
|
||||||
|
"hostname": resolve_hostname(rt.get("endpoint", "").split(":")[0]),
|
||||||
"handshake_ago": humanize_ago(ts, now),
|
"handshake_ago": humanize_ago(ts, now),
|
||||||
"rx": bytes_h(rt.get("rx_bytes", 0)),
|
"rx": bytes_h(rt.get("rx_bytes", 0)),
|
||||||
"tx": bytes_h(rt.get("tx_bytes", 0)),
|
"tx": bytes_h(rt.get("tx_bytes", 0)),
|
||||||
@@ -337,6 +359,7 @@ def index():
|
|||||||
"routes": imported_routes,
|
"routes": imported_routes,
|
||||||
"allowed_ips": rt.get("allowed_ips", "-"),
|
"allowed_ips": rt.get("allowed_ips", "-"),
|
||||||
"endpoint": rt.get("endpoint", "-"),
|
"endpoint": rt.get("endpoint", "-"),
|
||||||
|
"hostname": resolve_hostname(rt.get("endpoint", "").split(":")[0]),
|
||||||
"handshake_ago": humanize_ago(ts, now),
|
"handshake_ago": humanize_ago(ts, now),
|
||||||
"rx": bytes_h(rt.get("rx_bytes", 0)),
|
"rx": bytes_h(rt.get("rx_bytes", 0)),
|
||||||
"tx": bytes_h(rt.get("tx_bytes", 0)),
|
"tx": bytes_h(rt.get("tx_bytes", 0)),
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ tbody tr.row-disabled td { opacity: 0.45; }
|
|||||||
.text-muted { color: var(--text-muted); }
|
.text-muted { color: var(--text-muted); }
|
||||||
|
|
||||||
.pubkey { font-family: var(--mono); font-size: 11px; color: var(--text-muted); cursor: default; }
|
.pubkey { font-family: var(--mono); font-size: 11px; color: var(--text-muted); cursor: default; }
|
||||||
|
.hostname { font-size: 11px; color: var(--accent); font-weight: 500; }
|
||||||
|
|
||||||
.empty { text-align: center; padding: 40px !important; color: var(--text-muted); }
|
.empty { text-align: center; padding: 40px !important; color: var(--text-muted); }
|
||||||
.empty a { color: var(--accent); text-decoration: none; }
|
.empty a { color: var(--accent); text-decoration: none; }
|
||||||
|
|||||||
@@ -40,7 +40,10 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="mono-sm">{{ p.client_address }}</td>
|
<td class="mono-sm">{{ p.client_address }}</td>
|
||||||
<td class="mono-sm text-muted">{{ p.routes }}</td>
|
<td class="mono-sm text-muted">{{ p.routes }}</td>
|
||||||
<td class="mono-sm text-muted">{{ p.endpoint }}</td>
|
<td>
|
||||||
|
<span class="mono-sm text-muted">{{ p.endpoint }}</span>
|
||||||
|
{% if p.hostname %}<br><span class="hostname">{{ p.hostname }}</span>{% endif %}
|
||||||
|
</td>
|
||||||
<td class="text-muted traffic">
|
<td class="text-muted traffic">
|
||||||
<span title="Получено">↓ {{ p.rx }}</span>
|
<span title="Получено">↓ {{ p.rx }}</span>
|
||||||
<span title="Отправлено">↑ {{ p.tx }}</span>
|
<span title="Отправлено">↑ {{ p.tx }}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user