agent v0.3.15: mode proxy auto/manuel, correction auto-update et conservation systray, animation UI update
This commit is contained in:
+104
-4
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -169,8 +170,107 @@ func notifyUI(msg map[string]interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func startWebSocket(serverAddr, nodeID, dataDir, headscaleURL, headscaleAuthKey string) {
|
||||
setHeadscaleConfig(headscaleURL, headscaleAuthKey)
|
||||
// directDialer returns a websocket.Dialer that never uses a proxy.
|
||||
func directDialer() *websocket.Dialer {
|
||||
d := websocket.DefaultDialer
|
||||
return &websocket.Dialer{
|
||||
Proxy: nil,
|
||||
HandshakeTimeout: d.HandshakeTimeout,
|
||||
ReadBufferSize: d.ReadBufferSize,
|
||||
WriteBufferSize: d.WriteBufferSize,
|
||||
EnableCompression: d.EnableCompression,
|
||||
}
|
||||
}
|
||||
|
||||
// proxyOnlyDialer returns a websocket.Dialer that always uses the configured
|
||||
// proxy URL, ignoring the current auto-proxy state.
|
||||
func proxyOnlyDialer(cfg *AgentConfig) *websocket.Dialer {
|
||||
d := websocket.DefaultDialer
|
||||
u := proxyURL(cfg)
|
||||
if u == nil {
|
||||
return d
|
||||
}
|
||||
return &websocket.Dialer{
|
||||
Proxy: func(*http.Request) (*url.URL, error) { return u, nil },
|
||||
HandshakeTimeout: d.HandshakeTimeout,
|
||||
ReadBufferSize: d.ReadBufferSize,
|
||||
WriteBufferSize: d.WriteBufferSize,
|
||||
EnableCompression: d.EnableCompression,
|
||||
}
|
||||
}
|
||||
|
||||
// dialServerWithFallback attempts to connect to the WebSocket server according
|
||||
// to the configured proxy mode. In auto mode it tries direct connections first
|
||||
// and falls back to the proxy after a few failures.
|
||||
func dialServerWithFallback(cfg *AgentConfig, serverAddr string, headers http.Header) (*websocket.Conn, error) {
|
||||
mode := proxyMode(cfg)
|
||||
|
||||
switch mode {
|
||||
case ProxyModeDisabled:
|
||||
conn, _, err := directDialer().Dial(serverAddr, headers)
|
||||
return conn, err
|
||||
case ProxyModeEnabled:
|
||||
conn, _, err := websocketDialer(cfg).Dial(serverAddr, headers)
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// Auto mode.
|
||||
u := proxyURL(cfg)
|
||||
if u == nil {
|
||||
conn, _, err := directDialer().Dial(serverAddr, headers)
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// If we are currently in auto-proxy mode, try direct again only after the
|
||||
// lock duration has expired. Otherwise stay on the proxy.
|
||||
if IsProxyActive() {
|
||||
if canRetryDirect() {
|
||||
log.Println("Auto proxy: retrying direct connection after lock period")
|
||||
conn, _, err := directDialer().Dial(serverAddr, headers)
|
||||
if err == nil {
|
||||
if setProxyActive(false) {
|
||||
log.Println("Auto proxy: switched back to direct connection")
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
log.Printf("Auto proxy: direct retry failed (%v), keeping proxy", err)
|
||||
}
|
||||
conn, _, err := proxyOnlyDialer(cfg).Dial(serverAddr, headers)
|
||||
if err != nil {
|
||||
// Proxy failed too: clear the active flag so next round restarts the
|
||||
// direct-first fallback sequence.
|
||||
setProxyActive(false)
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// Not currently in proxy mode: try direct up to 3 times, then proxy.
|
||||
for i := 0; i < 3; i++ {
|
||||
conn, _, err := directDialer().Dial(serverAddr, headers)
|
||||
if err == nil {
|
||||
return conn, nil
|
||||
}
|
||||
log.Printf("Auto proxy: direct attempt %d/%d failed: %v", i+1, 3, err)
|
||||
if i < 2 {
|
||||
time.Sleep(3 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Auto proxy: falling back to proxy")
|
||||
conn, _, err := proxyOnlyDialer(cfg).Dial(serverAddr, headers)
|
||||
if err == nil {
|
||||
if setProxyActive(true) {
|
||||
log.Println("Auto proxy: switched to proxy")
|
||||
}
|
||||
} else {
|
||||
log.Printf("Auto proxy: proxy fallback failed: %v", err)
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
func startWebSocket(cfg *AgentConfig, nodeID, dataDir string) {
|
||||
setHeadscaleConfig(cfg.HeadscaleURL, cfg.HeadscaleAuthKey)
|
||||
serverAddr := cfg.Server
|
||||
|
||||
for {
|
||||
token, _ := loadNodeToken(dataDir)
|
||||
@@ -179,14 +279,14 @@ func startWebSocket(serverAddr, nodeID, dataDir, headscaleURL, headscaleAuthKey
|
||||
headers.Set("Authorization", "Bearer "+token)
|
||||
}
|
||||
|
||||
conn, _, err := websocket.DefaultDialer.Dial(serverAddr, headers)
|
||||
conn, err := dialServerWithFallback(cfg, serverAddr, headers)
|
||||
if err != nil {
|
||||
log.Printf("WS connect error: %v, retrying in 5s...", err)
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("WS connected to %s (token=%v)", serverAddr, token != "")
|
||||
log.Printf("WS connected to %s (token=%v, proxy=%v)", serverAddr, token != "", IsProxyActive())
|
||||
|
||||
mainConnMu.Lock()
|
||||
mainConn = conn
|
||||
|
||||
Reference in New Issue
Block a user