From ea4fd08464bf2c61e9fee95d8aeed2c02e1ec387 Mon Sep 17 00:00:00 2001 From: evenhummus Date: Wed, 4 Jun 2025 15:14:50 +0200 Subject: [PATCH] fix: complete server lockup when a lot of clients connect --- server/clients/clientdata/client.go | 12 +++++++++++- server/clients/payloads.go | 15 ++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/server/clients/clientdata/client.go b/server/clients/clientdata/client.go index b38ad6ab..9d61f330 100644 --- a/server/clients/clientdata/client.go +++ b/server/clients/clientdata/client.go @@ -519,6 +519,9 @@ func (c *Client) ToCalculated(allGroups []*cgroups.ClientGroup) *CalculatedClien // If a given duration is nil - returns false (never obsolete). func (c *Client) Obsolete(duration *time.Duration) bool { disconnectedAt := c.GetDisconnectedAt() + if disconnectedAt == nil { + return false + } return duration != nil && !c.IsConnected() && disconnectedAt.Add(*duration).Before(Now()) } @@ -627,7 +630,7 @@ func (c *Client) BelongsTo(group *cgroups.ClientGroup) bool { return false } - if !p.ConnectionState.MatchesOneOf(string(c.CalculateConnectionState())) { + if !p.ConnectionState.MatchesOneOf(string(c.calculateConnectionStateUnlocked())) { return false } @@ -641,6 +644,13 @@ func (c *Client) CalculateConnectionState() ConnectionState { return Disconnected } +func (c *Client) calculateConnectionStateUnlocked() ConnectionState { + if c.DisconnectedAt != nil { + return Connected + } + return Disconnected +} + // HasAccessViaUserGroups returns true if at least one of given user groups has access to a current client. func (c *Client) HasAccessViaUserGroups(userGroups []string) bool { for _, curUserGroup := range userGroups { diff --git a/server/clients/payloads.go b/server/clients/payloads.go index 124c06e8..d4b3ae12 100644 --- a/server/clients/payloads.go +++ b/server/clients/payloads.go @@ -1,6 +1,7 @@ package clients import ( + "strings" "time" "github.com/openrport/openrport/server/clients/clientdata" @@ -58,14 +59,16 @@ func ConvertToClientsPayload(clientsList []*clientdata.CalculatedClient, fields func ConvertToClientPayload(client *clientdata.CalculatedClient, fields []query.FieldsOption) ClientPayload { //nolint:gocyclo requestedFields := query.RequestedFields(fields, "clients") p := ClientPayload{} + + //Source Fellows change + client.GetLock().RLock() + defer client.GetLock().RUnlock() + for field := range OptionsSupportedFields["clients"] { if len(fields) > 0 && !requestedFields[field] { continue } - client.GetLock().RLock() - defer client.GetLock().RUnlock() - switch field { case "id": id := client.ID @@ -74,7 +77,8 @@ func ConvertToClientPayload(client *clientdata.CalculatedClient, fields []query. name := client.Name p.Name = &name case "os": - p.OS = &client.OS + val := strings.Clone(client.OS) + p.OS = &val case "os_arch": p.OSArch = &client.OSArch case "os_family": @@ -82,7 +86,8 @@ func ConvertToClientPayload(client *clientdata.CalculatedClient, fields []query. case "os_kernel": p.OSKernel = &client.OSKernel case "hostname": - p.Hostname = &client.Hostname + val := client.Hostname + p.Hostname = &val case "ipv4": p.IPv4 = &client.IPv4 case "ipv6":