client: Fix a lot of bugs around setting NICK

This commit is contained in:
Daniel Oaks 2016-11-29 22:33:10 +10:00
parent 5eafd2656e
commit a8eabe8e9c
3 changed files with 19 additions and 24 deletions

View File

@ -358,9 +358,12 @@ func (client *Client) SetNickname(nickname string) error {
return ErrNickAlreadySet return ErrNickAlreadySet
} }
client.nick = nickname err := client.server.clients.Add(client, nickname)
client.updateNick() if err == nil {
return client.server.clients.Add(client) client.nick = nickname
client.updateNick()
}
return err
} }
// ChangeNickname changes the existing nickname of the client. // ChangeNickname changes the existing nickname of the client.

View File

@ -48,8 +48,8 @@ func NewClientLookupSet() *ClientLookupSet {
func (clients *ClientLookupSet) Count() int { func (clients *ClientLookupSet) Count() int {
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock()
count := len(clients.ByNick) count := len(clients.ByNick)
clients.ByNickMutex.Unlock()
return count return count
} }
@ -60,8 +60,8 @@ func (clients *ClientLookupSet) Has(nick string) bool {
return false return false
} }
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock()
_, exists := clients.ByNick[casefoldedName] _, exists := clients.ByNick[casefoldedName]
clients.ByNickMutex.Unlock()
return exists return exists
} }
@ -79,23 +79,24 @@ func (clients *ClientLookupSet) Get(nick string) *Client {
casefoldedName, err := CasefoldName(nick) casefoldedName, err := CasefoldName(nick)
if err == nil { if err == nil {
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock()
cli := clients.ByNick[casefoldedName] cli := clients.ByNick[casefoldedName]
clients.ByNickMutex.Unlock()
return cli return cli
} }
return nil return nil
} }
func (clients *ClientLookupSet) Add(client *Client) error { func (clients *ClientLookupSet) Add(client *Client, nick string) error {
if !client.HasNick() { nick, err := CasefoldName(nick)
return ErrNickMissing if err != nil {
return err
} }
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock() defer clients.ByNickMutex.Unlock()
if clients.getNoMutex(client.nick) != nil { if clients.getNoMutex(nick) != nil {
return ErrNicknameInUse return ErrNicknameInUse
} }
clients.ByNick[client.nickCasefolded] = client clients.ByNick[nick] = client
return nil return nil
} }
@ -104,12 +105,11 @@ func (clients *ClientLookupSet) Remove(client *Client) error {
return ErrNickMissing return ErrNickMissing
} }
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock()
if clients.getNoMutex(client.nick) != client { if clients.getNoMutex(client.nick) != client {
clients.ByNickMutex.Unlock()
return ErrNicknameMismatch return ErrNicknameMismatch
} }
delete(clients.ByNick, client.nickCasefolded) delete(clients.ByNick, client.nickCasefolded)
clients.ByNickMutex.Unlock()
return nil return nil
} }
@ -150,6 +150,7 @@ func (clients *ClientLookupSet) AllWithCaps(caps ...Capability) (set ClientSet)
set = make(ClientSet) set = make(ClientSet)
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock()
var client *Client var client *Client
for _, client = range clients.ByNick { for _, client = range clients.ByNick {
// make sure they have all the required caps // make sure they have all the required caps
@ -161,7 +162,6 @@ func (clients *ClientLookupSet) AllWithCaps(caps ...Capability) (set ClientSet)
set.Add(client) set.Add(client)
} }
clients.ByNickMutex.Unlock()
return set return set
} }
@ -176,12 +176,12 @@ func (clients *ClientLookupSet) FindAll(userhost string) (set ClientSet) {
matcher := ircmatch.MakeMatch(userhost) matcher := ircmatch.MakeMatch(userhost)
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock()
for _, client := range clients.ByNick { for _, client := range clients.ByNick {
if matcher.Match(client.nickMaskCasefolded) { if matcher.Match(client.nickMaskCasefolded) {
set.Add(client) set.Add(client)
} }
} }
clients.ByNickMutex.Unlock()
return set return set
} }
@ -195,13 +195,13 @@ func (clients *ClientLookupSet) Find(userhost string) *Client {
var matchedClient *Client var matchedClient *Client
clients.ByNickMutex.Lock() clients.ByNickMutex.Lock()
defer clients.ByNickMutex.Unlock()
for _, client := range clients.ByNick { for _, client := range clients.ByNick {
if matcher.Match(client.nickMaskCasefolded) { if matcher.Match(client.nickMaskCasefolded) {
matchedClient = client matchedClient = client
break break
} }
} }
clients.ByNickMutex.Unlock()
return matchedClient return matchedClient
} }

View File

@ -658,13 +658,6 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
return true return true
} }
// set user info and log client in
//TODO(dan): Could there be a race condition here with adding/removing the client?
//TODO(dan): we should do something like server.clients.Replace(client) instead
// we do it this way to ONLY replace what hasn't already been set
server.clients.Remove(client)
if !client.HasUsername() { if !client.HasUsername() {
client.username = "~" + msg.Params[0] client.username = "~" + msg.Params[0]
// don't bother updating nickmask here, it's not valid anyway // don't bother updating nickmask here, it's not valid anyway
@ -673,7 +666,6 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
client.realname = msg.Params[3] client.realname = msg.Params[3]
} }
server.clients.Add(client)
server.tryRegister(client) server.tryRegister(client)
return false return false