Release 2.6.2: disconnect AWG without freezing the UI.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -243,6 +243,9 @@ https://evilfox.win/
|
||||
|
||||
Некоторые AV (Bkav, Microsoft Wacapew/Wacatac, Ikarus Trojan.WinGo.Agent, Google, Trapmine) часто помечают **любые** неподписанные Go-бинарники с сетью и сменой системного прокси.
|
||||
|
||||
В 2.6.2:
|
||||
- быстрое отключение AWG: принудительно закрываются прокси-соединения, UI больше не зависает.
|
||||
|
||||
В 2.6.1:
|
||||
- AmneziaWG: перед подключением Endpoint-хост резолвится в IP (предпочтительно IPv4) — обход сбоя IpcSet на Windows («No such host is known»).
|
||||
|
||||
|
||||
+3
-3
@@ -28,11 +28,11 @@ if errorlevel 1 exit /b 1
|
||||
go build -o "tools\packmac\packmac.exe" .\tools\packmac
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-arm64\Navis" -out "dist\navis-release\darwin-arm64" -version 2.6.1 -arch arm64
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-arm64\Navis" -out "dist\navis-release\darwin-arm64" -version 2.6.2 -arch arm64
|
||||
if errorlevel 1 exit /b 1
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-amd64\Navis" -out "dist\navis-release\darwin-amd64" -version 2.6.1 -arch amd64
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-amd64\Navis" -out "dist\navis-release\darwin-amd64" -version 2.6.2 -arch amd64
|
||||
if errorlevel 1 exit /b 1
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-universal\Navis" -out "dist\navis-release\darwin-universal" -version 2.6.1 -arch universal
|
||||
tools\packmac\packmac.exe -bin "dist\navis-release\darwin-universal\Navis" -out "dist\navis-release\darwin-universal" -version 2.6.2 -arch universal
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
echo Built:
|
||||
|
||||
@@ -296,8 +296,7 @@ func (a *app) connectProfile(name string) error {
|
||||
}
|
||||
|
||||
func (a *app) disconnect() error {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
// Do not hold a.mu across engine teardown — getState polling would freeze the UI.
|
||||
return a.mgr.Disconnect()
|
||||
}
|
||||
|
||||
|
||||
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Vendored
+7
-7
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"version": "2.6.1",
|
||||
"notes": "AWG: любой hostname Endpoint резолвится в IP до подключения (фикс No such host is known)",
|
||||
"version": "2.6.2",
|
||||
"notes": "Быстрое отключение AWG без зависания UI («приложение не отвечает»)",
|
||||
"platform": "windows-amd64",
|
||||
"os": "windows",
|
||||
"arch": "amd64",
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "08f001a3850ca5bd4f73b7ba4d21e8664ee9fc8120a87877f35d8f20a5ed6993",
|
||||
"sha256": "14fe9afb7978433a811662175ed21e9f65e66420c105ef943ca6f11aeeada072",
|
||||
"mandatory": false,
|
||||
"platforms": {
|
||||
"windows-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "08f001a3850ca5bd4f73b7ba4d21e8664ee9fc8120a87877f35d8f20a5ed6993",
|
||||
"sha256": "14fe9afb7978433a811662175ed21e9f65e66420c105ef943ca6f11aeeada072",
|
||||
"os": "windows",
|
||||
"arch": "amd64"
|
||||
},
|
||||
"darwin-arm64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis",
|
||||
"sha256": "b67e8b3fb5db8b97f85dba4c0d307c137c67fb6b56b36f8b2a7adf327ff226d4",
|
||||
"sha256": "497cdf66b74e28061622debbbc6fa922ae64ae532e867dec876188af15e85278",
|
||||
"os": "darwin",
|
||||
"arch": "arm64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg",
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"darwin-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis",
|
||||
"sha256": "37385c52cb397f60acc699adecb0ffc1843106d50288b1304393daf63083b4b7",
|
||||
"sha256": "95ccb649116bd15cbcdddccdd57df77651bf5f41ec19a4c6a0e91f8139621df7",
|
||||
"os": "darwin",
|
||||
"arch": "amd64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg",
|
||||
@@ -32,7 +32,7 @@
|
||||
},
|
||||
"darwin-universal": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis",
|
||||
"sha256": "ce250733cc7f5ed50b42f5cc106be9872b057966e7a73bcee78974d85748c2fb",
|
||||
"sha256": "abdb4d5807145dfab7afa1fc9fd4d0382a4f5d9b4ce7621128b2b393c7f0c928",
|
||||
"os": "darwin",
|
||||
"arch": "universal",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg",
|
||||
|
||||
Vendored
+7
-7
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"version": "2.6.1",
|
||||
"notes": "AWG: любой hostname Endpoint резолвится в IP до подключения (фикс No such host is known)",
|
||||
"version": "2.6.2",
|
||||
"notes": "Быстрое отключение AWG без зависания UI («приложение не отвечает»)",
|
||||
"platform": "windows-amd64",
|
||||
"os": "windows",
|
||||
"arch": "amd64",
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "08f001a3850ca5bd4f73b7ba4d21e8664ee9fc8120a87877f35d8f20a5ed6993",
|
||||
"sha256": "14fe9afb7978433a811662175ed21e9f65e66420c105ef943ca6f11aeeada072",
|
||||
"mandatory": false,
|
||||
"platforms": {
|
||||
"windows-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "08f001a3850ca5bd4f73b7ba4d21e8664ee9fc8120a87877f35d8f20a5ed6993",
|
||||
"sha256": "14fe9afb7978433a811662175ed21e9f65e66420c105ef943ca6f11aeeada072",
|
||||
"os": "windows",
|
||||
"arch": "amd64"
|
||||
},
|
||||
"darwin-arm64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis",
|
||||
"sha256": "b67e8b3fb5db8b97f85dba4c0d307c137c67fb6b56b36f8b2a7adf327ff226d4",
|
||||
"sha256": "497cdf66b74e28061622debbbc6fa922ae64ae532e867dec876188af15e85278",
|
||||
"os": "darwin",
|
||||
"arch": "arm64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg",
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"darwin-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis",
|
||||
"sha256": "37385c52cb397f60acc699adecb0ffc1843106d50288b1304393daf63083b4b7",
|
||||
"sha256": "95ccb649116bd15cbcdddccdd57df77651bf5f41ec19a4c6a0e91f8139621df7",
|
||||
"os": "darwin",
|
||||
"arch": "amd64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg",
|
||||
@@ -32,7 +32,7 @@
|
||||
},
|
||||
"darwin-universal": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis",
|
||||
"sha256": "ce250733cc7f5ed50b42f5cc106be9872b057966e7a73bcee78974d85748c2fb",
|
||||
"sha256": "abdb4d5807145dfab7afa1fc9fd4d0382a4f5d9b4ce7621128b2b393c7f0c928",
|
||||
"os": "darwin",
|
||||
"arch": "universal",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg",
|
||||
|
||||
@@ -725,7 +725,7 @@
|
||||
<div class="brand-wrap">
|
||||
<div class="brand-row">
|
||||
<h1 class="brand">Navis</h1>
|
||||
<span class="badge-ver">2.6.1</span>
|
||||
<span class="badge-ver">2.6.2</span>
|
||||
</div>
|
||||
<p class="tagline">Быстрый клиент · Naive · Hy2 · AWG · Xray</p>
|
||||
</div>
|
||||
|
||||
@@ -100,21 +100,33 @@ func (m *Manager) Connect(ctx context.Context, profileName string) error {
|
||||
|
||||
func (m *Manager) Disconnect() error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
sys := m.sys
|
||||
engine := m.engine
|
||||
m.engine = nil
|
||||
m.profile = nil
|
||||
m.mu.Unlock()
|
||||
|
||||
var first error
|
||||
if m.sys.Enabled() {
|
||||
if err := m.sys.Disable(); err != nil && first == nil {
|
||||
if sys != nil && sys.Enabled() {
|
||||
if err := sys.Disable(); err != nil && first == nil {
|
||||
first = err
|
||||
}
|
||||
}
|
||||
if m.engine != nil {
|
||||
if err := m.engine.Stop(); err != nil && first == nil {
|
||||
if engine != nil {
|
||||
done := make(chan error, 1)
|
||||
go func() { done <- engine.Stop() }()
|
||||
select {
|
||||
case err := <-done:
|
||||
if err != nil && first == nil {
|
||||
first = err
|
||||
}
|
||||
m.engine = nil
|
||||
case <-time.After(3 * time.Second):
|
||||
// Engine Stop can block on userspace relays; don't freeze the UI.
|
||||
if first == nil {
|
||||
first = fmt.Errorf("отключение заняло слишком много времени")
|
||||
}
|
||||
}
|
||||
}
|
||||
m.profile = nil
|
||||
return first
|
||||
}
|
||||
|
||||
|
||||
@@ -120,15 +120,16 @@ func (e *Engine) stopLocked() error {
|
||||
if !e.running {
|
||||
return nil
|
||||
}
|
||||
if e.proxies != nil {
|
||||
_ = e.proxies.Close()
|
||||
e.proxies = nil
|
||||
}
|
||||
// Close device first so tun/netstack dials fail and relays exit promptly.
|
||||
if e.dev != nil {
|
||||
e.dev.Close()
|
||||
e.dev = nil
|
||||
}
|
||||
e.tnet = nil
|
||||
if e.proxies != nil {
|
||||
_ = e.proxies.Close()
|
||||
e.proxies = nil
|
||||
}
|
||||
e.running = false
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -25,10 +25,14 @@ type proxyServer struct {
|
||||
closed bool
|
||||
socksAddr string
|
||||
httpAddr string
|
||||
conns map[net.Conn]struct{}
|
||||
}
|
||||
|
||||
func startProxies(socksHostPort, httpHostPort string, dial DialFunc) (*proxyServer, error) {
|
||||
s := &proxyServer{dial: dial}
|
||||
s := &proxyServer{
|
||||
dial: dial,
|
||||
conns: make(map[net.Conn]struct{}),
|
||||
}
|
||||
if socksHostPort != "" {
|
||||
ln, err := net.Listen("tcp", socksHostPort)
|
||||
if err != nil {
|
||||
@@ -53,6 +57,22 @@ func startProxies(socksHostPort, httpHostPort string, dial DialFunc) (*proxyServ
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *proxyServer) track(c net.Conn) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if s.closed {
|
||||
_ = c.Close()
|
||||
return
|
||||
}
|
||||
s.conns[c] = struct{}{}
|
||||
}
|
||||
|
||||
func (s *proxyServer) untrack(c net.Conn) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
delete(s.conns, c)
|
||||
}
|
||||
|
||||
func (s *proxyServer) Close() error {
|
||||
s.mu.Lock()
|
||||
if s.closed {
|
||||
@@ -66,8 +86,23 @@ func (s *proxyServer) Close() error {
|
||||
if s.httpLn != nil {
|
||||
_ = s.httpLn.Close()
|
||||
}
|
||||
// Force-close active relays so io.Copy / dial wake up immediately.
|
||||
for c := range s.conns {
|
||||
_ = c.Close()
|
||||
}
|
||||
s.conns = nil
|
||||
s.mu.Unlock()
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
s.wg.Wait()
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(1500 * time.Millisecond):
|
||||
// Don't hang UI / Disconnect on stuck netstack copies.
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -81,6 +116,8 @@ func (s *proxyServer) serveSOCKS() {
|
||||
s.wg.Add(1)
|
||||
go func(conn net.Conn) {
|
||||
defer s.wg.Done()
|
||||
s.track(conn)
|
||||
defer s.untrack(conn)
|
||||
_ = handleSOCKS(conn, s.dial)
|
||||
}(c)
|
||||
}
|
||||
@@ -96,6 +133,8 @@ func (s *proxyServer) serveHTTP() {
|
||||
s.wg.Add(1)
|
||||
go func(conn net.Conn) {
|
||||
defer s.wg.Done()
|
||||
s.track(conn)
|
||||
defer s.untrack(conn)
|
||||
_ = handleHTTPProxy(conn, s.dial)
|
||||
}(c)
|
||||
}
|
||||
@@ -156,7 +195,7 @@ func handleSOCKS(client net.Conn, dial DialFunc) error {
|
||||
port := binary.BigEndian.Uint16(buf[:2])
|
||||
_ = client.SetDeadline(time.Time{})
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
remote, err := dial(ctx, "tcp", net.JoinHostPort(host, fmt.Sprintf("%d", port)))
|
||||
if err != nil {
|
||||
@@ -185,7 +224,7 @@ func handleHTTPProxy(client net.Conn, dial DialFunc) error {
|
||||
if !strings.Contains(host, ":") {
|
||||
host += ":443"
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
remote, err := dial(ctx, "tcp", host)
|
||||
if err != nil {
|
||||
@@ -212,7 +251,7 @@ func handleHTTPProxy(client net.Conn, dial DialFunc) error {
|
||||
if !strings.Contains(host, ":") {
|
||||
host += ":80"
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
remote, err := dial(ctx, "tcp", host)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// CurrentVersion is the shipped client version.
|
||||
const CurrentVersion = "2.6.1"
|
||||
const CurrentVersion = "2.6.2"
|
||||
|
||||
// DefaultManifestURL is the update feed (hosted in the project git repo).
|
||||
const DefaultManifestURL = "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/update.json"
|
||||
|
||||
+7
-7
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"version": "2.6.1",
|
||||
"notes": "AWG: любой hostname Endpoint резолвится в IP до подключения (фикс No such host is known)",
|
||||
"version": "2.6.2",
|
||||
"notes": "Быстрое отключение AWG без зависания UI («приложение не отвечает»)",
|
||||
"platform": "windows-amd64",
|
||||
"os": "windows",
|
||||
"arch": "amd64",
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "08f001a3850ca5bd4f73b7ba4d21e8664ee9fc8120a87877f35d8f20a5ed6993",
|
||||
"sha256": "14fe9afb7978433a811662175ed21e9f65e66420c105ef943ca6f11aeeada072",
|
||||
"mandatory": false,
|
||||
"platforms": {
|
||||
"windows-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe",
|
||||
"sha256": "08f001a3850ca5bd4f73b7ba4d21e8664ee9fc8120a87877f35d8f20a5ed6993",
|
||||
"sha256": "14fe9afb7978433a811662175ed21e9f65e66420c105ef943ca6f11aeeada072",
|
||||
"os": "windows",
|
||||
"arch": "amd64"
|
||||
},
|
||||
"darwin-arm64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis",
|
||||
"sha256": "b67e8b3fb5db8b97f85dba4c0d307c137c67fb6b56b36f8b2a7adf327ff226d4",
|
||||
"sha256": "497cdf66b74e28061622debbbc6fa922ae64ae532e867dec876188af15e85278",
|
||||
"os": "darwin",
|
||||
"arch": "arm64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg",
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"darwin-amd64": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis",
|
||||
"sha256": "37385c52cb397f60acc699adecb0ffc1843106d50288b1304393daf63083b4b7",
|
||||
"sha256": "95ccb649116bd15cbcdddccdd57df77651bf5f41ec19a4c6a0e91f8139621df7",
|
||||
"os": "darwin",
|
||||
"arch": "amd64",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg",
|
||||
@@ -32,7 +32,7 @@
|
||||
},
|
||||
"darwin-universal": {
|
||||
"url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis",
|
||||
"sha256": "ce250733cc7f5ed50b42f5cc106be9872b057966e7a73bcee78974d85748c2fb",
|
||||
"sha256": "abdb4d5807145dfab7afa1fc9fd4d0382a4f5d9b4ce7621128b2b393c7f0c928",
|
||||
"os": "darwin",
|
||||
"arch": "universal",
|
||||
"dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg",
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"FixedFileInfo": {
|
||||
"FileVersion": { "Major": 2, "Minor": 6, "Patch": 1, "Build": 0 },
|
||||
"ProductVersion": { "Major": 2, "Minor": 6, "Patch": 1, "Build": 0 },
|
||||
"FileVersion": { "Major": 2, "Minor": 6, "Patch": 2, "Build": 0 },
|
||||
"ProductVersion": { "Major": 2, "Minor": 6, "Patch": 2, "Build": 0 },
|
||||
"FileFlagsMask": "3f",
|
||||
"FileFlags": "00",
|
||||
"FileOS": "40004",
|
||||
@@ -11,12 +11,12 @@
|
||||
"StringFileInfo": {
|
||||
"CompanyName": "EvilFox",
|
||||
"FileDescription": "Navis 2 — VPN client (Naive / Hy2 / AWG / VLESS / VMess / Trojan)",
|
||||
"FileVersion": "2.6.1.0",
|
||||
"FileVersion": "2.6.2.0",
|
||||
"InternalName": "Navis",
|
||||
"LegalCopyright": "Copyright (c) EvilFox",
|
||||
"OriginalFilename": "Navis.exe",
|
||||
"ProductName": "Navis",
|
||||
"ProductVersion": "2.6.1.0",
|
||||
"ProductVersion": "2.6.2.0",
|
||||
"Comments": "Open-source VPN/proxy client. https://evilfox.win/"
|
||||
},
|
||||
"VarFileInfo": {
|
||||
|
||||
Reference in New Issue
Block a user