From 72e5870269b34fcc4124213a993950f6028849ce Mon Sep 17 00:00:00 2001 From: abhishek9686 Date: Sat, 4 Apr 2026 00:08:06 +0530 Subject: [PATCH 01/11] v1.5.1: set max open conns --- controllers/hosts.go | 28 ++++++++++++++++++++++------ db/sqlite.go | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/controllers/hosts.go b/controllers/hosts.go index 2422a996..5aeeb7db 100644 --- a/controllers/hosts.go +++ b/controllers/hosts.go @@ -698,25 +698,25 @@ func bulkDeleteHosts(w http.ResponseWriter, r *http.Request) { for _, idStr := range req.IDs { hostID, err := uuid.Parse(idStr) if err != nil { - slog.Error("bulk host delete: invalid host id", "id", idStr) + slog.Debug("bulk host delete: invalid host id", "id", idStr) continue } currHost := &schema.Host{ID: hostID} if err = currHost.Get(db.WithContext(context.Background())); err != nil { - slog.Error("bulk host delete: host not found", "id", idStr, "error", err) + slog.Debug("bulk host delete: host not found", "id", idStr, "error", err) continue } var hostNodes []models.Node for _, nodeID := range currHost.Nodes { node, err := logic.GetNodeByID(nodeID) if err != nil { - slog.Error("bulk host delete: failed to get node", "nodeid", nodeID, "error", err) + slog.Debug("bulk host delete: failed to get node", "nodeid", nodeID, "error", err) continue } hostNodes = append(hostNodes, node) } if err = logic.RemoveHost(currHost, true); err != nil { - slog.Error("bulk host delete: failed to remove host", "id", idStr, "error", err) + slog.Debug("bulk host delete: failed to remove host", "id", idStr, "error", err) continue } for _, node := range hostNodes { @@ -724,14 +724,14 @@ func bulkDeleteHosts(w http.ResponseWriter, r *http.Request) { } if servercfg.GetBrokerType() == servercfg.EmqxBrokerType { if err := mq.GetEmqxHandler().DeleteEmqxUser(currHost.ID.String()); err != nil { - slog.Error("bulk host delete: failed to remove EMQX credentials", "id", currHost.ID, "error", err) + slog.Debug("bulk host delete: failed to remove EMQX credentials", "id", currHost.ID, "error", err) } } if err = mq.HostUpdate(&models.HostUpdate{ Action: models.DeleteHost, Host: *currHost, }); err != nil { - slog.Error("bulk host delete: failed to send host update", "id", currHost.ID, "error", err) + slog.Debug("bulk host delete: failed to send host update", "id", currHost.ID, "error", err) } (&schema.PendingHost{HostID: currHost.ID.String()}).DeleteAllPendingHosts(db.WithContext(context.TODO())) logic.LogEvent(&models.Event{ @@ -1632,6 +1632,22 @@ func approvePendingHost(w http.ResponseWriter, r *http.Request) { }) } p.Delete(db.WithContext(r.Context())) + logic.LogEvent(&models.Event{ + Action: schema.JoinHostToNet, + Source: models.Subject{ + ID: key.Value, + Name: key.Tags[0], + Type: schema.EnrollmentKeySub, + }, + TriggeredBy: r.Header.Get("user"), + Target: models.Subject{ + ID: h.ID.String(), + Name: h.Name, + Type: schema.DeviceSub, + }, + NetworkID: schema.NetworkID(p.Network), + Origin: schema.Dashboard, + }) go mq.PublishPeerUpdate(false) logic.ReturnSuccessResponseWithJson(w, r, newNode.ConvertToAPINode(), "added pending host to "+p.Network) } diff --git a/db/sqlite.go b/db/sqlite.go index 22a6f96a..6e3df11f 100644 --- a/db/sqlite.go +++ b/db/sqlite.go @@ -62,6 +62,7 @@ func (s *sqliteConnector) connect() (*gorm.DB, error) { return nil, err } + sqlDB.SetMaxOpenConns(1) sqlDB.SetMaxIdleConns(1) return db, nil From 0cdb885f50e21ea98f593f618d29999477334044 Mon Sep 17 00:00:00 2001 From: abhishek9686 Date: Sat, 4 Apr 2026 21:58:25 +0530 Subject: [PATCH 02/11] revet log change --- controllers/hosts.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/controllers/hosts.go b/controllers/hosts.go index 5aeeb7db..154faf9a 100644 --- a/controllers/hosts.go +++ b/controllers/hosts.go @@ -1632,22 +1632,6 @@ func approvePendingHost(w http.ResponseWriter, r *http.Request) { }) } p.Delete(db.WithContext(r.Context())) - logic.LogEvent(&models.Event{ - Action: schema.JoinHostToNet, - Source: models.Subject{ - ID: key.Value, - Name: key.Tags[0], - Type: schema.EnrollmentKeySub, - }, - TriggeredBy: r.Header.Get("user"), - Target: models.Subject{ - ID: h.ID.String(), - Name: h.Name, - Type: schema.DeviceSub, - }, - NetworkID: schema.NetworkID(p.Network), - Origin: schema.Dashboard, - }) go mq.PublishPeerUpdate(false) logic.ReturnSuccessResponseWithJson(w, r, newNode.ConvertToAPINode(), "added pending host to "+p.Network) } From 6a522ae8576a4e0c14986ff8b10e75fc89e048fc Mon Sep 17 00:00:00 2001 From: abhishek9686 Date: Mon, 6 Apr 2026 05:36:51 +0530 Subject: [PATCH 03/11] v1.5.1: deduplicate egress routes --- logic/extpeers.go | 1 + logic/peers.go | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/logic/extpeers.go b/logic/extpeers.go index 77ccdc38..54649a05 100644 --- a/logic/extpeers.go +++ b/logic/extpeers.go @@ -684,6 +684,7 @@ func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRo NodeAddr: node.Address, NodeAddr6: node.Address6, EgressRanges: extPeer.ExtraAllowedIPs, + Network: node.Network, } for _, extraAllowedIP := range extPeer.ExtraAllowedIPs { r.EgressRangesWithMetric = append(r.EgressRangesWithMetric, models.EgressRangeMetric{ diff --git a/logic/peers.go b/logic/peers.go index bbfb5d3d..fbf889cb 100644 --- a/logic/peers.go +++ b/logic/peers.go @@ -238,14 +238,14 @@ func computeHostPeerInfo(host *schema.Host, allNodes []models.Node, serverInfo m // GetPeerUpdateForHost - gets the consolidated peer update for the host from all networks func GetPeerUpdateForHost(network string, host *schema.Host, allNodes []models.Node, - deletedNode *models.Node, deletedClients []models.ExtClient) (models.HostPeerUpdate, error) { + deletedNode *models.Node, deletedClients []models.ExtClient) (hostPeerUpdate models.HostPeerUpdate, err error) { if host == nil { return models.HostPeerUpdate{}, errors.New("host is nil") } // track which nodes are deleted // after peer calculation, if peer not in list, add delete config of peer - hostPeerUpdate := models.HostPeerUpdate{ + hostPeerUpdate = models.HostPeerUpdate{ Host: *host, Server: servercfg.GetServer(), ServerVersion: servercfg.GetVersion(), @@ -266,6 +266,9 @@ func GetPeerUpdateForHost(network string, host *schema.Host, allNodes []models.N GwNodes: make(map[schema.NetworkID][]models.Node), AddressIdentityMap: make(map[string]models.PeerIdentity), } + defer func() { + hostPeerUpdate.EgressRoutes = deduplicateEgressRoutes(hostPeerUpdate.EgressRoutes) + }() if host.DNS == "no" { hostPeerUpdate.ManageDNS = false } @@ -931,6 +934,18 @@ func getNodeAllowedIPs(peer, node *models.Node) []net.IPNet { } return allowedips } +func deduplicateEgressRoutes(routes []models.EgressNetworkRoutes) []models.EgressNetworkRoutes { + seen := make(map[string]struct{}, len(routes)) + result := make([]models.EgressNetworkRoutes, 0, len(routes)) + for _, r := range routes { + key := r.PeerKey + "|" + r.Network + if _, exists := seen[key]; !exists { + seen[key] = struct{}{} + result = append(result, r) + } + } + return result +} func getCIDRMaskFromAddr(addr string) net.IPMask { cidr := net.CIDRMask(32, 32) From 96e1d92e484f830a34ab38f87f29c7e61641af42 Mon Sep 17 00:00:00 2001 From: VishalDalwadi Date: Mon, 6 Apr 2026 22:44:04 +0530 Subject: [PATCH 04/11] fix(go): check only based on ip version; --- migrate/migrate_v1_5_1.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/migrate/migrate_v1_5_1.go b/migrate/migrate_v1_5_1.go index 443ef5e5..93f49d85 100644 --- a/migrate/migrate_v1_5_1.go +++ b/migrate/migrate_v1_5_1.go @@ -255,12 +255,19 @@ func migrateNetworks(ctx context.Context) error { } for _, nsIP := range network.NameServers { - if net.ParseIP(nsIP) == nil { + ip := net.ParseIP(nsIP) + if ip == nil { continue } - if (cidr != nil && !cidr.Contains(net.ParseIP(nsIP))) && - (cidrv6 != nil && !cidrv6.Contains(net.ParseIP(nsIP))) { - ns.Servers = append(ns.Servers, nsIP) + + if ip.To4() != nil { + if cidr != nil && !cidr.Contains(ip) { + ns.Servers = append(ns.Servers, nsIP) + } + } else { + if cidrv6 != nil && !cidrv6.Contains(ip) { + ns.Servers = append(ns.Servers, nsIP) + } } } From f4d5e3fa2f3d6b5199762bf1439e42b4767ce7a3 Mon Sep 17 00:00:00 2001 From: VishalDalwadi Date: Tue, 7 Apr 2026 15:48:57 +0530 Subject: [PATCH 05/11] fix(go): publish peer update post license validation; --- pro/license.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pro/license.go b/pro/license.go index ea49a927..94b1e0bb 100644 --- a/pro/license.go +++ b/pro/license.go @@ -141,6 +141,7 @@ func ValidateLicense() (err error) { proLogic.SetDeploymentMode(licenseResponse.DeploymentMode) _ = mq.PublishExporterFeatureFlags() + _ = mq.PublishPeerUpdate(false) slog.Info("License validation succeeded!") return nil From a5d27e9b8501b7f67a965504df531645a97af49e Mon Sep 17 00:00:00 2001 From: VishalDalwadi Date: Tue, 7 Apr 2026 15:54:46 +0530 Subject: [PATCH 06/11] fix(go): skip default host auto update reset; --- migrate/migrate_v1_5_1.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/migrate/migrate_v1_5_1.go b/migrate/migrate_v1_5_1.go index 93f49d85..7044241e 100644 --- a/migrate/migrate_v1_5_1.go +++ b/migrate/migrate_v1_5_1.go @@ -412,10 +412,6 @@ func migrateHosts(ctx context.Context) error { } } - if _host.IsDefault && !_host.AutoUpdate { - _host.AutoUpdate = true - } - logger.Log(4, fmt.Sprintf("migrating host %s", _host.ID)) err = _host.Create(ctx) From fdc45c4eb9fd1508ffa7918a3a6aa81355840d77 Mon Sep 17 00:00:00 2001 From: VishalDalwadi Date: Tue, 7 Apr 2026 15:58:03 +0530 Subject: [PATCH 07/11] fix(go): disable auto update for all hosts when setting disabled; --- controllers/server.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/controllers/server.go b/controllers/server.go index 649f370b..f6dccfdd 100644 --- a/controllers/server.go +++ b/controllers/server.go @@ -336,7 +336,8 @@ func reInit(curr, new models.ServerSettings, force bool) { // On force AutoUpdate change, change AutoUpdate for all hosts. // On force FlowLogs enable, enable FlowLogs for all hosts. // On FlowLogs disable, forced or not, disable FlowLogs for all hosts. - if force || !new.EnableFlowLogs { + // On NetclientAutoUpdate disable, forced or not, disable AutoUpdate for all hosts. + if force || !new.EnableFlowLogs || !new.NetclientAutoUpdate { if curr.NetclientAutoUpdate != new.NetclientAutoUpdate || curr.EnableFlowLogs != new.EnableFlowLogs { hosts, _ := (&schema.Host{}).ListAll(db.WithContext(context.TODO())) From 0afdf654590dc3c004d5e69efbf335436f81ffc9 Mon Sep 17 00:00:00 2001 From: VishalDalwadi Date: Tue, 7 Apr 2026 16:01:13 +0530 Subject: [PATCH 08/11] fix(go): add disabled egress mode; --- migrate/migrate.go | 3 +++ schema/egress.go | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/migrate/migrate.go b/migrate/migrate.go index 575e2495..e33d3879 100644 --- a/migrate/migrate.go +++ b/migrate/migrate.go @@ -589,6 +589,9 @@ func migrateToEgressV1() { CreatedBy: user.UserName, CreatedAt: time.Now().UTC(), } + if !e.Nat { + e.Mode = schema.DisabledNAT + } err = e.Create(db.WithContext(context.TODO())) if err == nil { acl := models.Acl{ diff --git a/schema/egress.go b/schema/egress.go index c9063d3f..628fe6cd 100644 --- a/schema/egress.go +++ b/schema/egress.go @@ -13,8 +13,9 @@ const egressTable = "egresses" type EgressNATMode string const ( - VirtualNAT EgressNATMode = "virtual_nat" - DirectNAT EgressNATMode = "direct_nat" + DisabledNAT EgressNATMode = "disabled" + VirtualNAT EgressNATMode = "virtual_nat" + DirectNAT EgressNATMode = "direct_nat" ) type Egress struct { From 660cd2fcfd653985d6f47ee43bb55df476155ca7 Mon Sep 17 00:00:00 2001 From: VishalDalwadi Date: Tue, 7 Apr 2026 16:14:30 +0530 Subject: [PATCH 09/11] fix(go): send mq messages in go routine; --- pro/license.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pro/license.go b/pro/license.go index 94b1e0bb..b3d87de3 100644 --- a/pro/license.go +++ b/pro/license.go @@ -140,8 +140,8 @@ func ValidateLicense() (err error) { proLogic.SetFeatureFlags(licenseResponse.FeatureFlags) proLogic.SetDeploymentMode(licenseResponse.DeploymentMode) - _ = mq.PublishExporterFeatureFlags() - _ = mq.PublishPeerUpdate(false) + go mq.PublishExporterFeatureFlags() + go mq.PublishPeerUpdate(false) slog.Info("License validation succeeded!") return nil From 09f19376c6080578c991f97b951d4c81ba1d4430 Mon Sep 17 00:00:00 2001 From: VishalDalwadi Date: Tue, 7 Apr 2026 17:59:50 +0530 Subject: [PATCH 10/11] fix(go): check for multiple ingress dns nameservers; --- migrate/migrate.go | 76 +++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/migrate/migrate.go b/migrate/migrate.go index e33d3879..9dcd562b 100644 --- a/migrate/migrate.go +++ b/migrate/migrate.go @@ -7,6 +7,7 @@ import ( "log" "net" "slices" + "strings" "time" "golang.org/x/exp/slog" @@ -841,42 +842,53 @@ func migrateNameservers() { if !node.IsGw { continue } + if node.IngressDNS != "" { - if (node.Address.IP != nil && node.Address.IP.String() == node.IngressDNS) || - (node.Address6.IP != nil && node.Address6.IP.String() == node.IngressDNS) { - continue + var nsIPs []string + for _, nsIP := range strings.Split(node.IngressDNS, ",") { + nsIP = strings.TrimSpace(nsIP) + + if (node.Address.IP != nil && node.Address.IP.String() == nsIP) || + (node.Address6.IP != nil && node.Address6.IP.String() == nsIP) { + continue + } + if nsIP == "8.8.8.8" || nsIP == "1.1.1.1" || nsIP == "9.9.9.9" { + continue + } + + nsIPs = append(nsIPs, nsIP) } - if node.IngressDNS == "8.8.8.8" || node.IngressDNS == "1.1.1.1" || node.IngressDNS == "9.9.9.9" { - continue - } - host := &schema.Host{ - ID: node.HostID, - } - err := host.Get(db.WithContext(context.TODO())) - if err != nil { - continue - } - ns := schema.Nameserver{ - ID: uuid.NewString(), - Name: fmt.Sprintf("%s gw nameservers", host.Name), - NetworkID: node.Network, - Servers: []string{node.IngressDNS}, - MatchAll: true, - Domains: []schema.NameserverDomain{ - { - Domain: ".", + + if len(nsIPs) > 0 { + host := &schema.Host{ + ID: node.HostID, + } + err := host.Get(db.WithContext(context.TODO())) + if err != nil { + continue + } + ns := schema.Nameserver{ + ID: uuid.NewString(), + Name: fmt.Sprintf("%s gw nameservers", host.Name), + NetworkID: node.Network, + Servers: nsIPs, + MatchAll: true, + Domains: []schema.NameserverDomain{ + { + Domain: ".", + }, }, - }, - Nodes: datatypes.JSONMap{ - node.ID.String(): struct{}{}, - }, - Tags: make(datatypes.JSONMap), - Status: true, - CreatedBy: superAdmin.Username, + Nodes: datatypes.JSONMap{ + node.ID.String(): struct{}{}, + }, + Tags: make(datatypes.JSONMap), + Status: true, + CreatedBy: superAdmin.Username, + } + _ = ns.Create(db.WithContext(context.TODO())) + node.IngressDNS = "" + _ = logic.UpsertNode(&node) } - _ = ns.Create(db.WithContext(context.TODO())) - node.IngressDNS = "" - _ = logic.UpsertNode(&node) } } } From 0c91a37e6e35431cf72b2533eb0684f85bdd10a4 Mon Sep 17 00:00:00 2001 From: abhishek9686 Date: Wed, 8 Apr 2026 13:19:03 +0530 Subject: [PATCH 11/11] v1.5.1: comment out max open conns --- db/sqlite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/sqlite.go b/db/sqlite.go index 6e3df11f..356c6203 100644 --- a/db/sqlite.go +++ b/db/sqlite.go @@ -62,7 +62,7 @@ func (s *sqliteConnector) connect() (*gorm.DB, error) { return nil, err } - sqlDB.SetMaxOpenConns(1) + //sqlDB.SetMaxOpenConns(1) sqlDB.SetMaxIdleConns(1) return db, nil