Index: trunk/upstream.go
===================================================================
--- trunk/upstream.go	(revision 752)
+++ trunk/upstream.go	(revision 757)
@@ -343,5 +343,5 @@
 		return
 	}
-	uc.SendMessage(uc.pendingCmds[cmd][0].msg)
+	uc.SendMessage(context.TODO(), uc.pendingCmds[cmd][0].msg)
 }
 
@@ -451,5 +451,5 @@
 	switch msg.Command {
 	case "PING":
-		uc.SendMessage(&irc.Message{
+		uc.SendMessage(ctx, &irc.Message{
 			Command: "PONG",
 			Params:  msg.Params,
@@ -530,5 +530,5 @@
 			}
 
-			uc.SendMessage(&irc.Message{
+			uc.SendMessage(ctx, &irc.Message{
 				Command: "CAP",
 				Params:  []string{"END"},
@@ -584,5 +584,5 @@
 		var challengeStr string
 		if err := parseMessageParams(msg, &challengeStr); err != nil {
-			uc.SendMessage(&irc.Message{
+			uc.SendMessage(ctx, &irc.Message{
 				Command: "AUTHENTICATE",
 				Params:  []string{"*"},
@@ -596,5 +596,5 @@
 			challenge, err = base64.StdEncoding.DecodeString(challengeStr)
 			if err != nil {
-				uc.SendMessage(&irc.Message{
+				uc.SendMessage(ctx, &irc.Message{
 					Command: "AUTHENTICATE",
 					Params:  []string{"*"},
@@ -613,5 +613,5 @@
 		}
 		if err != nil {
-			uc.SendMessage(&irc.Message{
+			uc.SendMessage(ctx, &irc.Message{
 				Command: "AUTHENTICATE",
 				Params:  []string{"*"},
@@ -626,5 +626,5 @@
 		}
 
-		uc.SendMessage(&irc.Message{
+		uc.SendMessage(ctx, &irc.Message{
 			Command: "AUTHENTICATE",
 			Params:  []string{respStr},
@@ -670,5 +670,5 @@
 
 		if !uc.registered {
-			uc.SendMessage(&irc.Message{
+			uc.SendMessage(ctx, &irc.Message{
 				Command: "CAP",
 				Params:  []string{"END"},
@@ -708,5 +708,5 @@
 
 			for _, msg := range join(channels, keys) {
-				uc.SendMessage(msg)
+				uc.SendMessage(ctx, msg)
 			}
 		}
@@ -932,5 +932,5 @@
 				uc.updateChannelAutoDetach(ch)
 
-				uc.SendMessage(&irc.Message{
+				uc.SendMessage(ctx, &irc.Message{
 					Command: "MODE",
 					Params:  []string{ch},
@@ -1532,5 +1532,5 @@
 			if found {
 				uc.logger.Printf("desired nick %q is now available", wantNick)
-				uc.SendMessage(&irc.Message{
+				uc.SendMessage(ctx, &irc.Message{
 					Command: "NICK",
 					Params:  []string{wantNick},
@@ -1712,5 +1712,5 @@
 			uc.nickCM = uc.network.casemap(uc.nick)
 			uc.logger.Printf("desired nick is not available, falling back to %q", uc.nick)
-			uc.SendMessage(&irc.Message{
+			uc.SendMessage(ctx, &irc.Message{
 				Command: "NICK",
 				Params:  []string{uc.nick},
@@ -1826,5 +1826,5 @@
 	}
 
-	uc.SendMessage(&irc.Message{
+	uc.SendMessage(context.TODO(), &irc.Message{
 		Command: "CAP",
 		Params:  []string{"REQ", strings.Join(requestCaps, " ")},
@@ -1883,5 +1883,5 @@
 		}
 
-		uc.SendMessage(&irc.Message{
+		uc.SendMessage(context.TODO(), &irc.Message{
 			Command: "AUTHENTICATE",
 			Params:  []string{auth.Mechanism},
@@ -1903,4 +1903,6 @@
 
 func (uc *upstreamConn) register() {
+	ctx := context.TODO()
+
 	uc.nick = GetNick(&uc.user.User, &uc.network.Network)
 	uc.nickCM = uc.network.casemap(uc.nick)
@@ -1908,5 +1910,5 @@
 	uc.realname = GetRealname(&uc.user.User, &uc.network.Network)
 
-	uc.SendMessage(&irc.Message{
+	uc.SendMessage(ctx, &irc.Message{
 		Command: "CAP",
 		Params:  []string{"LS", "302"},
@@ -1914,5 +1916,5 @@
 
 	if uc.network.Pass != "" {
-		uc.SendMessage(&irc.Message{
+		uc.SendMessage(ctx, &irc.Message{
 			Command: "PASS",
 			Params:  []string{uc.network.Pass},
@@ -1920,9 +1922,9 @@
 	}
 
-	uc.SendMessage(&irc.Message{
+	uc.SendMessage(ctx, &irc.Message{
 		Command: "NICK",
 		Params:  []string{uc.nick},
 	})
-	uc.SendMessage(&irc.Message{
+	uc.SendMessage(ctx, &irc.Message{
 		Command: "USER",
 		Params:  []string{uc.username, "0", "*", uc.realname},
@@ -1961,5 +1963,5 @@
 			uc.logger.Printf("failed to parse connect command %q: %v", command, err)
 		} else {
-			uc.SendMessage(m)
+			uc.SendMessage(context.TODO(), m)
 		}
 	}
@@ -1983,5 +1985,5 @@
 }
 
-func (uc *upstreamConn) SendMessage(msg *irc.Message) {
+func (uc *upstreamConn) SendMessage(ctx context.Context, msg *irc.Message) {
 	if !uc.caps["message-tags"] {
 		msg = msg.Copy()
@@ -1990,8 +1992,8 @@
 
 	uc.srv.metrics.upstreamOutMessagesTotal.Inc()
-	uc.conn.SendMessage(msg)
-}
-
-func (uc *upstreamConn) SendMessageLabeled(downstreamID uint64, msg *irc.Message) {
+	uc.conn.SendMessage(ctx, msg)
+}
+
+func (uc *upstreamConn) SendMessageLabeled(ctx context.Context, downstreamID uint64, msg *irc.Message) {
 	if uc.caps["labeled-response"] {
 		if msg.Tags == nil {
@@ -2001,5 +2003,5 @@
 		uc.nextLabelID++
 	}
-	uc.SendMessage(msg)
+	uc.SendMessage(ctx, msg)
 }
 
@@ -2074,4 +2076,6 @@
 
 func (uc *upstreamConn) updateAway() {
+	ctx := context.TODO()
+
 	away := true
 	uc.forEachDownstream(func(*downstreamConn) {
@@ -2082,10 +2086,10 @@
 	}
 	if away {
-		uc.SendMessage(&irc.Message{
+		uc.SendMessage(ctx, &irc.Message{
 			Command: "AWAY",
 			Params:  []string{"Auto away"},
 		})
 	} else {
-		uc.SendMessage(&irc.Message{
+		uc.SendMessage(ctx, &irc.Message{
 			Command: "AWAY",
 		})
@@ -2110,4 +2114,6 @@
 		return
 	}
+
+	ctx := context.TODO()
 
 	add := make(map[string]struct{})
@@ -2149,5 +2155,5 @@
 	if removeAll && len(addList) == 0 && len(removeList) > 0 {
 		// Optimization when the last MONITOR-aware downstream disconnects
-		uc.SendMessage(&irc.Message{
+		uc.SendMessage(ctx, &irc.Message{
 			Command: "MONITOR",
 			Params:  []string{"C"},
@@ -2157,5 +2163,5 @@
 		msgs = append(msgs, generateMonitor("+", addList)...)
 		for _, msg := range msgs {
-			uc.SendMessage(msg)
+			uc.SendMessage(ctx, msg)
 		}
 	}
