fix: multi issues - TUN read loop, SDWAN routing for TenantID=0, WS keepalive 10s
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Version info (set via -ldflags)
|
||||
@@ -46,8 +47,9 @@ type ServerConfig struct {
|
||||
CertFile string `json:"certFile"`
|
||||
KeyFile string `json:"keyFile"`
|
||||
LogLevel int `json:"logLevel"` // 0=debug, 1=info, 2=warn, 3=error
|
||||
Token uint64 `json:"token"` // master token for auth
|
||||
JWTKey string `json:"jwtKey"` // auto-generated if empty
|
||||
Token uint64 `json:"token"` // master token for auth
|
||||
Tokens []uint64 `json:"tokens"` // additional tenant tokens
|
||||
JWTKey string `json:"jwtKey"` // auto-generated if empty
|
||||
|
||||
AdminUser string `json:"adminUser"`
|
||||
AdminPass string `json:"adminPass"`
|
||||
@@ -82,6 +84,18 @@ func (c *ServerConfig) FillFromEnv() {
|
||||
if v := os.Getenv("INP2PS_TOKEN"); v != "" {
|
||||
c.Token, _ = strconv.ParseUint(v, 10, 64)
|
||||
}
|
||||
if v := os.Getenv("INP2PS_TOKENS"); v != "" {
|
||||
parts := strings.Split(v, ",")
|
||||
for _, p := range parts {
|
||||
p = strings.TrimSpace(p)
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
if tv, err := strconv.ParseUint(p, 10, 64); err == nil {
|
||||
c.Tokens = append(c.Tokens, tv)
|
||||
}
|
||||
}
|
||||
}
|
||||
if v := os.Getenv("INP2PS_CERT"); v != "" {
|
||||
c.CertFile = v
|
||||
}
|
||||
@@ -96,8 +110,8 @@ func (c *ServerConfig) FillFromEnv() {
|
||||
}
|
||||
|
||||
func (c *ServerConfig) Validate() error {
|
||||
if c.Token == 0 {
|
||||
return fmt.Errorf("token is required (INP2PS_TOKEN or -token)")
|
||||
if c.Token == 0 && len(c.Tokens) == 0 {
|
||||
return fmt.Errorf("token is required (INP2PS_TOKEN or INP2PS_TOKENS)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -108,6 +122,7 @@ type ClientConfig struct {
|
||||
ServerPort int `json:"serverPort"`
|
||||
Node string `json:"node"`
|
||||
Token uint64 `json:"token"`
|
||||
NodeSecret string `json:"nodeSecret,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
Insecure bool `json:"insecure"` // skip TLS verify
|
||||
|
||||
@@ -156,8 +171,8 @@ func (c *ClientConfig) Validate() error {
|
||||
if c.ServerHost == "" {
|
||||
return fmt.Errorf("serverHost is required")
|
||||
}
|
||||
if c.Token == 0 {
|
||||
return fmt.Errorf("token is required")
|
||||
if c.Token == 0 && c.NodeSecret == "" {
|
||||
return fmt.Errorf("token or nodeSecret is required")
|
||||
}
|
||||
if c.Node == "" {
|
||||
hostname, _ := os.Hostname()
|
||||
|
||||
@@ -192,6 +192,7 @@ func DecodePayload(data []byte, v interface{}) error {
|
||||
type LoginReq struct {
|
||||
Node string `json:"node"`
|
||||
Token uint64 `json:"token"`
|
||||
NodeSecret string `json:"nodeSecret,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
Version string `json:"version"`
|
||||
NATType NATType `json:"natType"`
|
||||
|
||||
@@ -103,6 +103,33 @@ func (c *Conn) Request(mainType, subType uint16, payload interface{},
|
||||
|
||||
// ReadLoop reads messages and dispatches to handlers. Blocks until error or Close().
|
||||
func (c *Conn) ReadLoop() error {
|
||||
// keepalive to avoid idle close (read deadline = 3x ping interval)
|
||||
_ = c.ws.SetReadDeadline(time.Now().Add(90 * time.Second))
|
||||
c.ws.SetPongHandler(func(string) error {
|
||||
_ = c.ws.SetReadDeadline(time.Now().Add(90 * time.Second))
|
||||
return nil
|
||||
})
|
||||
|
||||
// Send ping frames periodically to keep NAT/WSS alive
|
||||
// Increased frequency to 10s for better resilience against network hiccups
|
||||
go func() {
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-c.quit:
|
||||
return
|
||||
case <-ticker.C:
|
||||
c.writeMu.Lock()
|
||||
_ = c.ws.SetWriteDeadline(time.Now().Add(5 * time.Second))
|
||||
err := c.ws.WriteMessage(websocket.PingMessage, []byte(time.Now().Format("20060102150405")))
|
||||
if err != nil {
|
||||
log.Printf("[signal] ping failed: %v, will reconnect", err)
|
||||
}
|
||||
c.writeMu.Unlock()
|
||||
}
|
||||
}
|
||||
}()
|
||||
for {
|
||||
_, msg, err := c.ws.ReadMessage()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user