Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential Concurrency Issue with s.clients Access in Server #2

Open
beka-birhanu opened this issue Dec 12, 2024 · 1 comment
Open

Comments

@beka-birhanu
Copy link

beka-birhanu commented Dec 12, 2024

Description

The s.clients map in the Server structure appears to be accessed concurrently without proper synchronization, which may lead to race conditions.

  1. Example 1: Access in findClientBySessionID

    // returns the Client by the Session ID
    func (s *Server) findClientBySessionID(sessionID []byte) (*Client, bool) {
        for _, client := range s.clients {
            if bytes.Equal(client.sessionID, sessionID) {
                return client, true
            }
        }
        return nil, false
    }

    In this method, s.clients is iterated over, potentially while other parts of the code modify it.

  2. Example 2: Modification in Garbage Collection

    case <-s.garbageCollectionTicker.C:
        for _, c := range s.clients {
            if c.lastHeartbeat != nil && time.Now().After(c.lastHeartbeat.Add(s.heartbeatExpiration)) {
                delete(s.clients, c.ID)
                delete(s.sessions, fmt.Sprintf("%s_%d", c.addr.IP.String(), c.addr.Port))
            }
        }
    }

    The garbage collection routine iterates over and modifies s.clients concurrently, potentially leading to a panic due to a concurrent map read and write.

Problem

The s.clients map is not thread-safe. While one goroutine (e.g., the garbage collector) might be deleting clients, another goroutine (e.g., findClientBySessionID) could be iterating or reading from it, leading to undefined behavior or a runtime panic.

Suggestions

  1. Use sync.Map
    Replace s.clients with a sync.Map under a type wrapper. This will ensure thread-safe operations for both reading and writing.

  2. Introduce a Mutex
    Use a sync.Mutex or sync.RWMutex to explicitly lock the s.clients map during reads and writes. This approach ensures safety and maintains the existing map structure but could introduce performance overhead depending on the frequency of access.

@beka-birhanu beka-birhanu changed the title concurrency issue Potential Concurrency Issue with s.clients Access in Server Dec 12, 2024
@theredrad
Copy link
Owner

theredrad commented Dec 27, 2024

@beka-birhanu Hi, thanks for reviewing the code and creating issues, I made some quick changes. It would be great if you could review the changes here:

https://github.com/theredrad/udpsocket/pull/5/files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants