Index: trunk/downstream.go
===================================================================
--- trunk/downstream.go	(revision 715)
+++ trunk/downstream.go	(revision 716)
@@ -179,5 +179,6 @@
 
 // ' ' and ':' break the IRC message wire format, '@' and '!' break prefixes,
-// '*' and '?' break masks, '$' breaks server masks in PRIVMSG/NOTICE
+// '*' and '?' break masks, '$' breaks server masks in PRIVMSG/NOTICE,
+// "*" is the reserved nickname for registration
 const illegalNickChars = " :@!*?$"
 
@@ -281,4 +282,6 @@
 		conn:          *newConn(srv, ic, &options),
 		id:            id,
+		nick:          "*",
+		nickCM:        "*",
 		supportedCaps: make(map[string]string),
 		caps:          make(map[string]bool),
@@ -685,4 +688,5 @@
 		if !dc.caps["sasl"] {
 			return ircError{&irc.Message{
+				Prefix:  dc.srv.prefix(),
 				Command: irc.ERR_SASLFAIL,
 				Params:  []string{"*", "AUTHENTICATE requires the \"sasl\" capability to be enabled"},
@@ -691,12 +695,7 @@
 		if len(msg.Params) == 0 {
 			return ircError{&irc.Message{
+				Prefix:  dc.srv.prefix(),
 				Command: irc.ERR_SASLFAIL,
 				Params:  []string{"*", "Missing AUTHENTICATE argument"},
-			}}
-		}
-		if dc.nick == "" {
-			return ircError{&irc.Message{
-				Command: irc.ERR_SASLFAIL,
-				Params:  []string{"*", "Expected NICK command before AUTHENTICATE"},
 			}}
 		}
@@ -706,4 +705,5 @@
 			dc.saslServer = nil
 			return ircError{&irc.Message{
+				Prefix:  dc.srv.prefix(),
 				Command: irc.ERR_SASLABORTED,
 				Params:  []string{"*", "SASL authentication aborted"},
@@ -721,4 +721,5 @@
 			default:
 				return ircError{&irc.Message{
+					Prefix:  dc.srv.prefix(),
 					Command: irc.ERR_SASLFAIL,
 					Params:  []string{"*", fmt.Sprintf("Unsupported SASL mechanism %q", mech)},
@@ -734,4 +735,5 @@
 				dc.saslServer = nil
 				return ircError{&irc.Message{
+					Prefix:  dc.srv.prefix(),
 					Command: irc.ERR_SASLFAIL,
 					Params:  []string{"*", "Invalid base64-encoded response"},
@@ -745,4 +747,5 @@
 			if ircErr, ok := err.(ircError); ok && ircErr.Message.Command == irc.ERR_PASSWDMISMATCH {
 				return ircError{&irc.Message{
+					Prefix:  dc.srv.prefix(),
 					Command: irc.ERR_SASLFAIL,
 					Params:  []string{"*", ircErr.Message.Params[1]},
@@ -824,5 +827,5 @@
 		return newUnknownCommandError(msg.Command)
 	}
-	if dc.rawUsername != "" && dc.nick != "" && !dc.negotiatingCaps {
+	if dc.rawUsername != "" && dc.nick != "*" && !dc.negotiatingCaps {
 		return dc.register(ctx)
 	}
@@ -832,9 +835,4 @@
 func (dc *downstreamConn) handleCapCommand(cmd string, args []string) error {
 	cmd = strings.ToUpper(cmd)
-
-	replyTo := dc.nick
-	if !dc.registered {
-		replyTo = "*"
-	}
 
 	switch cmd {
@@ -868,5 +866,5 @@
 			Prefix:  dc.srv.prefix(),
 			Command: "CAP",
-			Params:  []string{replyTo, "LS", strings.Join(caps, " ")},
+			Params:  []string{dc.nick, "LS", strings.Join(caps, " ")},
 		})
 
@@ -891,5 +889,5 @@
 			Prefix:  dc.srv.prefix(),
 			Command: "CAP",
-			Params:  []string{replyTo, "LIST", strings.Join(caps, " ")},
+			Params:  []string{dc.nick, "LIST", strings.Join(caps, " ")},
 		})
 	case "REQ":
@@ -897,5 +895,5 @@
 			return ircError{&irc.Message{
 				Command: err_invalidcapcmd,
-				Params:  []string{replyTo, cmd, "Missing argument in CAP REQ command"},
+				Params:  []string{dc.nick, cmd, "Missing argument in CAP REQ command"},
 			}}
 		}
@@ -937,5 +935,5 @@
 			Prefix:  dc.srv.prefix(),
 			Command: "CAP",
-			Params:  []string{replyTo, reply, args[0]},
+			Params:  []string{dc.nick, reply, args[0]},
 		})
 
@@ -948,5 +946,5 @@
 		return ircError{&irc.Message{
 			Command: err_invalidcapcmd,
-			Params:  []string{replyTo, cmd, "Unknown CAP command"},
+			Params:  []string{dc.nick, cmd, "Unknown CAP command"},
 		}}
 	}
@@ -963,9 +961,4 @@
 	}
 
-	replyTo := dc.nick
-	if !dc.registered {
-		replyTo = "*"
-	}
-
 	cap := name
 	if value != "" && dc.capVersion >= 302 {
@@ -976,5 +969,5 @@
 		Prefix:  dc.srv.prefix(),
 		Command: "CAP",
-		Params:  []string{replyTo, "NEW", cap},
+		Params:  []string{dc.nick, "NEW", cap},
 	})
 }
@@ -989,13 +982,8 @@
 	}
 
-	replyTo := dc.nick
-	if !dc.registered {
-		replyTo = "*"
-	}
-
 	dc.SendMessage(&irc.Message{
 		Prefix:  dc.srv.prefix(),
 		Command: "CAP",
-		Params:  []string{replyTo, "DEL", name},
+		Params:  []string{dc.nick, "DEL", name},
 	})
 }
