mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-25 23:35:00 +03:00
35e09191de
AmneziaWG clients accept a randomised PersistentKeepalive range such as 15-25, which makes keepalive timing harder to fingerprint; the panel only stored a single number. A client's keepalive may now be a range, validated the way AmneziaWG parses it. The downloadable .conf and vpn:// profile carry the range, Clash/Mihomo output gets its lower bound, and plain WireGuard stays scalar-only. The range lives in an additive wg_keep_alive_range column, so the integer column and an older panel binary keep working after a rollback.
66 lines
1.8 KiB
Go
66 lines
1.8 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/mhsanaei/3x-ui/v3/internal/database/model"
|
|
)
|
|
|
|
func validateClientKeepAlive(protocol model.Protocol, client model.Client) error {
|
|
if client.KeepAlive == nil {
|
|
return nil
|
|
}
|
|
switch protocol {
|
|
case model.AmneziaWG:
|
|
return client.KeepAlive.Validate(true)
|
|
case model.WireGuard:
|
|
return client.KeepAlive.Validate(false)
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func validateClientsKeepAlive(protocol model.Protocol, clients []model.Client) error {
|
|
for _, client := range clients {
|
|
if err := validateClientKeepAlive(protocol, client); err != nil {
|
|
return fmt.Errorf("client %q: %w", client.Email, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateClientKeepAliveAgainstExisting(protocol model.Protocol, client model.Client, existing []model.Client, identityEmail ...string) error {
|
|
if err := validateClientKeepAlive(protocol, client); err == nil || client.KeepAlive == nil {
|
|
return err
|
|
}
|
|
if protocol != model.AmneziaWG && protocol != model.WireGuard {
|
|
return nil
|
|
}
|
|
value := client.KeepAlive.String()
|
|
identity := client.Email
|
|
if len(identityEmail) > 0 && identityEmail[0] != "" {
|
|
identity = identityEmail[0]
|
|
}
|
|
parsed, err := strconv.ParseInt(value, 10, 64)
|
|
if err != nil || strconv.FormatInt(parsed, 10) != value {
|
|
return validateClientKeepAlive(protocol, client)
|
|
}
|
|
for _, old := range existing {
|
|
if strings.EqualFold(old.Email, identity) && old.KeepAlive != nil && old.KeepAlive.String() == value {
|
|
return nil
|
|
}
|
|
}
|
|
return validateClientKeepAlive(protocol, client)
|
|
}
|
|
|
|
func validateClientsKeepAliveAgainstExisting(protocol model.Protocol, clients, existing []model.Client) error {
|
|
for _, client := range clients {
|
|
if err := validateClientKeepAliveAgainstExisting(protocol, client, existing); err != nil {
|
|
return fmt.Errorf("client %q: %w", client.Email, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|