fix: handshake bloqué par la passerelle dans les IPs autorisées
Quand la passerelle qui mène au serveur appartient à une plage des « IPs autorisées », wg-quick pose sa route vers le tunnel avec une métrique de 0. Elle bat la route de lien de la carte réseau : la passerelle n'est plus joignable que par le tunnel, alors que le tunnel a besoin d'elle pour sortir. Le tunnel montait, l'interface existait, et plus aucun paquet de handshake ne quittait la machine. Le diagnostic détecte désormais ce cas via _next_hop() (ip route get sous Linux, Find-NetRoute sous Windows) et le classe en échec, au lieu du simple avertissement sur l'imprimante et le NAS qui n'en disait pas la gravité. Corrige aussi le rapport de test de connexion : un QLabel que la mise en page comprimait à quelques lignes tronquées, remplacé par une zone de texte défilante ; la fenêtre d'administration, figée à 700x600, devient redimensionnable.
This commit is contained in:
+64
-27
@@ -66,6 +66,16 @@ _TAB_CSS = """
|
||||
"""
|
||||
|
||||
|
||||
_RESULT_CSS = (
|
||||
"QTextEdit { border: 1px solid rgba(255,255,255,0.12); border-radius: 6px;"
|
||||
" padding: 8px; font-size: 12px; }"
|
||||
"QScrollBar:vertical { background: transparent; width: 8px; border: none; }"
|
||||
"QScrollBar::handle:vertical { background: #2e4057; border-radius: 4px; }"
|
||||
"QScrollBar::add-line:vertical,"
|
||||
"QScrollBar::sub-line:vertical { height: 0; }"
|
||||
)
|
||||
|
||||
|
||||
class AdminWindow(QDialog):
|
||||
def __init__(self, config: Config, parent=None):
|
||||
super().__init__(parent)
|
||||
@@ -76,15 +86,24 @@ class AdminWindow(QDialog):
|
||||
| Qt.WindowType.WindowTitleHint
|
||||
| Qt.WindowType.WindowCloseButtonHint
|
||||
)
|
||||
self.setFixedSize(700, 600)
|
||||
# Taille figée auparavant : le rapport de diagnostic, long d'une
|
||||
# dizaine d'étapes détaillées, était comprimé en une bande illisible.
|
||||
self.setMinimumSize(720, 620)
|
||||
self.resize(880, 740)
|
||||
self._build_ui()
|
||||
self._load_values()
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Helper : page sombre avec bandeau coloré
|
||||
# ------------------------------------------------------------------ #
|
||||
def _dark_page(self, banner_text: str, banner_color: str):
|
||||
"""Retourne (page_widget, body_layout) : fond sombre + bandeau."""
|
||||
def _dark_page(self, banner_text: str, banner_color: str,
|
||||
scroll: bool = False):
|
||||
"""Retourne (page_widget, body_layout) : fond sombre + bandeau.
|
||||
|
||||
`scroll=True` place le corps dans une zone défilante : indispensable
|
||||
pour les pages dont le contenu grandit à l'usage (rapport de
|
||||
diagnostic), sinon les widgets se compriment jusqu'à l'illisible.
|
||||
"""
|
||||
w = QWidget()
|
||||
w.setStyleSheet(_TAB_CSS)
|
||||
outer = QVBoxLayout(w)
|
||||
@@ -103,7 +122,25 @@ class AdminWindow(QDialog):
|
||||
body_layout = QVBoxLayout(body)
|
||||
body_layout.setContentsMargins(14, 14, 14, 14)
|
||||
body_layout.setSpacing(10)
|
||||
outer.addWidget(body)
|
||||
|
||||
if scroll:
|
||||
from PyQt6.QtWidgets import QScrollArea
|
||||
body.setStyleSheet("background: #1c2833;")
|
||||
area = QScrollArea()
|
||||
area.setWidgetResizable(True)
|
||||
area.setStyleSheet(
|
||||
"QScrollArea { border: none; background: #1c2833; }"
|
||||
"QScrollBar:vertical { background: #1c2833; width: 8px;"
|
||||
" border: none; }"
|
||||
"QScrollBar::handle:vertical { background: #2e4057;"
|
||||
" border-radius: 4px; }"
|
||||
"QScrollBar::add-line:vertical,"
|
||||
"QScrollBar::sub-line:vertical { height: 0; }"
|
||||
)
|
||||
area.setWidget(body)
|
||||
outer.addWidget(area)
|
||||
else:
|
||||
outer.addWidget(body)
|
||||
return w, body_layout
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
@@ -456,7 +493,8 @@ class AdminWindow(QDialog):
|
||||
# Onglet Test connexion
|
||||
# ------------------------------------------------------------------ #
|
||||
def _tab_test(self) -> QWidget:
|
||||
w, lay = self._dark_page("📡 Test de connectivité réseau", "#1a4a7a")
|
||||
w, lay = self._dark_page("📡 Test de connectivité réseau", "#1a4a7a",
|
||||
scroll=True)
|
||||
|
||||
# Test UDP serveur
|
||||
grp1 = QGroupBox("Diagnostic de la chaîne de connexion")
|
||||
@@ -474,20 +512,22 @@ class AdminWindow(QDialog):
|
||||
)
|
||||
btn_test.clicked.connect(self._run_test)
|
||||
g1.addWidget(btn_test)
|
||||
self._test_result = QLabel("")
|
||||
self._test_result.setWordWrap(True)
|
||||
self._test_result.setTextFormat(Qt.TextFormat.RichText)
|
||||
self._test_result.setAlignment(
|
||||
Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
|
||||
# QLabel auparavant : le rapport fait une dizaine d'étapes avec un
|
||||
# détail par étape, et un QLabel se laisse écraser par le layout —
|
||||
# le texte était rogné à quelques lignes illisibles. Une vue en
|
||||
# lecture seule porte sa propre barre de défilement : le rapport reste
|
||||
# entier quelle que soit la taille de la fenêtre.
|
||||
self._test_result = QTextEdit()
|
||||
self._test_result.setReadOnly(True)
|
||||
self._test_result.setMinimumHeight(320)
|
||||
self._test_result.setSizePolicy(
|
||||
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding
|
||||
)
|
||||
self._test_result.setTextInteractionFlags(
|
||||
Qt.TextInteractionFlag.TextSelectableByMouse
|
||||
)
|
||||
self._test_result.setStyleSheet(
|
||||
"color: white; padding: 8px; border-radius: 6px; font-size: 12px;"
|
||||
)
|
||||
g1.addWidget(self._test_result)
|
||||
lay.addWidget(grp1)
|
||||
self._test_result.setStyleSheet(_RESULT_CSS + "color: white;")
|
||||
g1.addWidget(self._test_result, 1)
|
||||
# Facteur d'étirement : l'espace vertical libre revient au rapport de
|
||||
# diagnostic plutôt qu'au ressort de fin de page.
|
||||
lay.addWidget(grp1, 1)
|
||||
|
||||
# Test DNS leak
|
||||
grp2 = QGroupBox("🔍 Test de fuite DNS")
|
||||
@@ -528,7 +568,6 @@ class AdminWindow(QDialog):
|
||||
g3.addWidget(self._priv_result)
|
||||
lay.addWidget(grp3)
|
||||
|
||||
lay.addStretch()
|
||||
return w
|
||||
|
||||
def _refresh_profile_list(self):
|
||||
@@ -705,7 +744,7 @@ class AdminWindow(QDialog):
|
||||
name_lbl.setStyleSheet("color: white;")
|
||||
layout.addWidget(name_lbl)
|
||||
|
||||
version_lbl = QLabel("Version 0.4.5")
|
||||
version_lbl = QLabel("Version 0.4.6")
|
||||
version_lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
version_lbl.setStyleSheet("color: rgba(255,255,255,0.7); font-size: 13px;")
|
||||
layout.addWidget(version_lbl)
|
||||
@@ -905,14 +944,14 @@ class AdminWindow(QDialog):
|
||||
def _run_test(self):
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
self._save_values()
|
||||
self._test_result.setText("Diagnostic en cours…")
|
||||
self._test_result.setStyleSheet(
|
||||
"color: rgba(255,255,255,0.6); padding: 12px; border-radius: 6px; font-size: 13px;"
|
||||
self._test_result.setHtml(
|
||||
'<span style="color:rgba(255,255,255,0.6);">Diagnostic en cours…</span>'
|
||||
)
|
||||
self._test_result.setStyleSheet(_RESULT_CSS + "color: rgba(255,255,255,0.6);")
|
||||
QApplication.processEvents()
|
||||
|
||||
steps = wg_core.diagnose_connection(self._cfg)
|
||||
self._test_result.setText(self._format_diagnostic(steps))
|
||||
self._test_result.setHtml(self._format_diagnostic(steps))
|
||||
|
||||
states = [s["state"] for s in steps]
|
||||
if "fail" in states:
|
||||
@@ -921,9 +960,7 @@ class AdminWindow(QDialog):
|
||||
css = "background: rgba(241,196,15,0.15); color: #f7dc6f;"
|
||||
else:
|
||||
css = "background: rgba(39,174,96,0.20); color: #a9dfbf;"
|
||||
self._test_result.setStyleSheet(
|
||||
"padding: 12px; border-radius: 6px; font-size: 12px; " + css
|
||||
)
|
||||
self._test_result.setStyleSheet(_RESULT_CSS + "QTextEdit { " + css + " }")
|
||||
|
||||
def _format_diagnostic(self, steps: list[dict]) -> str:
|
||||
"""Met en forme les étapes ; la première en échec porte le verdict."""
|
||||
|
||||
Reference in New Issue
Block a user