Skip to content

Commit 9044df2

Browse files
committed
Fix race condition on clients map
1 parent 1d2d13f commit 9044df2

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

internal/app/rcon/server.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Server struct {
2727
listener net.Listener
2828
running bool
2929
mutex sync.Mutex
30+
clientsMutex sync.Mutex
3031
}
3132

3233
type Client struct {
@@ -76,12 +77,35 @@ func (s *Server) Stop() {
7677
if err := s.listener.Close(); err != nil {
7778
log.Printf("Could not close listener: %v", err)
7879
}
79-
for id := range s.clients {
80+
for _, id := range s.GetClientIds() {
8081
s.CloseConnection(id)
8182
}
8283
s.listener = nil
8384
}
8485

86+
func (s *Server) GetClient(id string) (*Client, bool) {
87+
s.clientsMutex.Lock()
88+
defer s.clientsMutex.Unlock()
89+
client, ok := s.clients[id]
90+
return client, ok
91+
}
92+
93+
func (s *Server) PutClient(id string, client *Client) {
94+
s.clientsMutex.Lock()
95+
defer s.clientsMutex.Unlock()
96+
s.clients[id] = client
97+
}
98+
99+
func (s *Server) GetClientIds() []string {
100+
s.clientsMutex.Lock()
101+
defer s.clientsMutex.Unlock()
102+
var clients []string
103+
for k := range s.clients {
104+
clients = append(clients, k)
105+
}
106+
return clients
107+
}
108+
85109
func (s *Server) listen() {
86110
log.Print("Listening on ", s.address)
87111

@@ -132,6 +156,8 @@ func (s *Server) loadTlsConfig() (*tls.Config, error) {
132156
}
133157

134158
func (s *Server) CloseConnection(id string) {
159+
s.clientsMutex.Lock()
160+
defer s.clientsMutex.Unlock()
135161
delete(s.clients, id)
136162
log.Printf("Connection to %v closed", id)
137163
}

internal/app/rcon/server_autoref.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,8 @@ func (c *AutoRefClient) receiveRegistration(reader *bufio.Reader, server *AutoRe
3939
return errors.New("No identifier specified")
4040
}
4141
c.id = *registration.Identifier
42-
if _, exists := server.clients[c.id]; exists {
43-
var clients []string
44-
for k := range server.clients {
45-
clients = append(clients, k)
46-
}
47-
return errors.Errorf("AutoRef Client with given identifier already registered: %v", clients)
42+
if _, exists := server.GetClient(c.id); exists {
43+
return errors.Errorf("AutoRef Client with given identifier already registered: %v", server.GetClientIds())
4844
}
4945
c.pubKey = server.trustedKeys[c.id]
5046
if c.pubKey != nil {
@@ -78,7 +74,7 @@ func (s *AutoRefServer) handleClientConnection(conn net.Conn) {
7874
return
7975
}
8076

81-
s.clients[client.id] = client.Client
77+
s.PutClient(client.id, client.Client)
8278
defer func() {
8379
s.gcEngine.UpdateGcState(func(gcState *engine.GcState) {
8480
delete(gcState.AutoRefState, client.id)

internal/app/rcon/server_remotecontrol.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func (c *RemoteControlClient) receiveRegistration(reader *bufio.Reader, server *
4848
}
4949
c.team = registration.Team
5050
c.id = registration.Team.String()
51-
if _, exists := server.clients[c.id]; exists {
51+
if _, exists := server.GetClient(c.id); exists {
5252
return errors.New("Team already registered: " + c.id)
5353
}
5454
c.pubKey = server.trustedKeys[c.id]
@@ -88,7 +88,7 @@ func (s *RemoteControlServer) handleClientConnection(conn net.Conn) {
8888
return
8989
}
9090

91-
s.clients[client.id] = client.Client
91+
s.PutClient(client.id, client.Client)
9292
defer func() {
9393
s.updateConnectionState(client, false)
9494
s.CloseConnection(client.id)
@@ -130,7 +130,7 @@ func (s *RemoteControlServer) updateConnectionState(client RemoteControlClient,
130130
}
131131

132132
func (s *RemoteControlServer) SendRequest(teamName string, request *ControllerToRemoteControl) error {
133-
if client, ok := s.clients[teamName]; ok {
133+
if client, ok := s.GetClient(teamName); ok {
134134
return sslconn.SendMessage(client.conn, request)
135135
}
136136
return errors.Errorf("Remote control client '%v' not connected", teamName)

internal/app/rcon/server_team.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (c *TeamClient) receiveRegistration(reader *bufio.Reader, server *TeamServe
6464
c.id = team.String() + "-" + *registration.TeamName
6565
c.team = team
6666
c.teamName = *registration.TeamName
67-
if _, exists := server.clients[c.id]; exists {
67+
if _, exists := server.GetClient(c.id); exists {
6868
return errors.New("Team with given name already registered: " + c.id)
6969
}
7070
c.pubKey = server.trustedKeys[*registration.TeamName]
@@ -110,7 +110,7 @@ func (s *TeamServer) handleClientConnection(conn net.Conn) {
110110
return
111111
}
112112

113-
s.clients[client.id] = client.Client
113+
s.PutClient(client.id, client.Client)
114114
defer func() {
115115
s.gcEngine.UpdateGcState(func(gcState *engine.GcState) {
116116
if teamState, ok := gcState.TeamState[client.team.String()]; ok {
@@ -157,7 +157,7 @@ func (s *TeamServer) handleClientConnection(conn net.Conn) {
157157
}
158158

159159
func (s *TeamServer) SendRequest(teamName string, request *ControllerToTeam) error {
160-
if client, ok := s.clients[teamName]; ok {
160+
if client, ok := s.GetClient(teamName); ok {
161161
return sslconn.SendMessage(client.conn, request)
162162
}
163163
return errors.Errorf("Team Client '%v' not connected", teamName)

0 commit comments

Comments
 (0)