From 8a526131716a31819b1b79c31ccb7a03272c7383 Mon Sep 17 00:00:00 2001 From: chteufleur Date: Sat, 1 Jul 2017 16:59:05 +0200 Subject: [PATCH] Fixe concurrent map read and map write for XMPP remote roster request. --- gateway/gateway.go | 29 ++++++++++++++++++++++++++++- gateway/xmpp.go | 11 ++++++----- xmpp/xmpp.go | 4 ++-- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/gateway/gateway.go b/gateway/gateway.go index 415963a..1075993 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -34,7 +34,7 @@ type GatewayInfo struct { XMPP_Out chan interface{} xmpp_Connected_Client *XmppConnectedClient DebugMessage bool - XMPP_IQ_RemoteRoster_Request map[string]string + xmpp_IQ_RemoteRoster_Request *XmppRemoteRosterRequest AllowEditRoster bool ChatstateNotificationData chan string } @@ -49,6 +49,11 @@ type XmppConnectedClient struct { sync.RWMutex } +type XmppRemoteRosterRequest struct { + request map[string]string + sync.RWMutex +} + type StatusSteamFriend struct { XMPP_Status string XMPP_Type string @@ -137,3 +142,25 @@ func (s *GatewayInfo) GetLenXmppConnectedClient() int { defer s.xmpp_Connected_Client.RUnlock() return len(s.xmpp_Connected_Client.client) } + +func (s *GatewayInfo) CreateXmppRemoteRosterRequest() { + s.xmpp_IQ_RemoteRoster_Request = &XmppRemoteRosterRequest{request: make(map[string]string)} +} + +func (s *GatewayInfo) SetXmppRemoteRosterRequest(iqId, value string) { + s.xmpp_IQ_RemoteRoster_Request.Lock() + s.xmpp_IQ_RemoteRoster_Request.request[iqId] = value + s.xmpp_IQ_RemoteRoster_Request.Unlock() +} + +func (s *GatewayInfo) RemoveXmppRemoteRosterRequest(iqId string) { + s.xmpp_IQ_RemoteRoster_Request.Lock() + delete(s.xmpp_IQ_RemoteRoster_Request.request, iqId) + s.xmpp_IQ_RemoteRoster_Request.Unlock() +} + +func (s *GatewayInfo) GetXmppRemoteRosterRequest(iqId string) string { + s.xmpp_IQ_RemoteRoster_Request.RLock() + defer s.xmpp_IQ_RemoteRoster_Request.RUnlock() + return s.xmpp_IQ_RemoteRoster_Request.request[iqId] +} diff --git a/gateway/xmpp.go b/gateway/xmpp.go index 8650f1c..4ad5df2 100644 --- a/gateway/xmpp.go +++ b/gateway/xmpp.go @@ -138,8 +138,9 @@ func (g *GatewayInfo) ReceivedXMPP_Message(message *xmpp.Message) { func (g *GatewayInfo) ReceivedXMPP_IQ(iq *xmpp.IQ) bool { ret := false - if g.XMPP_IQ_RemoteRoster_Request[iq.ID] == RemoteRosterRequestPermission { - delete(g.XMPP_IQ_RemoteRoster_Request, iq.ID) + remoteRosterRequestValue := g.GetXmppRemoteRosterRequest(iq.ID) + if remoteRosterRequestValue == RemoteRosterRequestPermission { + g.RemoveXmppRemoteRosterRequest(iq.ID) if iq.Type == xmpp.IQTypeError && iq.Error.Condition() == xmpp.ErrorForbidden { g.AllowEditRoster = false @@ -160,15 +161,15 @@ func (g *GatewayInfo) ReceivedXMPP_IQ(iq *xmpp.IQ) bool { logger.Info.Printf("Check roster edition authorisation by querying roster's user") // Remote roster namespace may not be supported (like prosody), so we send a roster query iqId := NextIqId() - g.XMPP_IQ_RemoteRoster_Request[iqId] = RemoteRosterRequestRoster + g.SetXmppRemoteRosterRequest(iqId, RemoteRosterRequestRoster) iqSend := &xmpp.IQ{ID: iqId, Type: xmpp.IQTypeGet, From: iq.To, To: iq.From} iqSend.PayloadEncode(&xmpp.RosterQuery{}) g.XMPP_Out <- iqSend } ret = true - } else if g.XMPP_IQ_RemoteRoster_Request[iq.ID] == RemoteRosterRequestRoster { - delete(g.XMPP_IQ_RemoteRoster_Request, iq.ID) + } else if remoteRosterRequestValue == RemoteRosterRequestRoster { + g.RemoveXmppRemoteRosterRequest(iq.ID) if iq.Type == xmpp.IQTypeResult && iq.PayloadName().Space == xmpp.NSRoster { g.AllowEditRoster = true } else { diff --git a/xmpp/xmpp.go b/xmpp/xmpp.go index 3c5ff3c..30f7223 100644 --- a/xmpp/xmpp.go +++ b/xmpp/xmpp.go @@ -283,7 +283,7 @@ func AddNewUser(jidUser, steamLogin, steamPwd string, debugMessage bool) { g.XMPP_Out = comp.Out g.CreateXmppConnectedClient() g.DebugMessage = debugMessage - g.XMPP_IQ_RemoteRoster_Request = make(map[string]string) + g.CreateXmppRemoteRosterRequest() g.AllowEditRoster = false MapGatewayInfo[jidUser] = g @@ -292,7 +292,7 @@ func AddNewUser(jidUser, steamLogin, steamPwd string, debugMessage bool) { logger.Info.Printf("Check roster edition by asking with remote roster manager namespace") // Ask if remote roster is allow iqId := gateway.NextIqId() - g.XMPP_IQ_RemoteRoster_Request[iqId] = gateway.RemoteRosterRequestPermission + g.SetXmppRemoteRosterRequest(iqId, gateway.RemoteRosterRequestPermission) iq := xmpp.IQ{To: jidUser, From: jid.Domain, Type: xmpp.IQTypeGet, ID: iqId} // iq.PayloadEncode(&xmpp.RosterQuery{}) iq.PayloadEncode(&xmpp.RemoteRosterManagerQuery{Reason: "Manage contacts in the Steam contact list", Type: xmpp.RemoteRosterManagerTypeRequest})