Index: /trunk/downstream.go
===================================================================
--- /trunk/downstream.go	(revision 275)
+++ /trunk/downstream.go	(revision 276)
@@ -54,10 +54,10 @@
 // capabilities.
 var permanentDownstreamCaps = map[string]string{
-	"batch": "",
-	"cap-notify": "",
+	"batch":        "",
+	"cap-notify":   "",
 	"echo-message": "",
 	"message-tags": "",
-	"sasl": "PLAIN",
-	"server-time": "",
+	"sasl":         "PLAIN",
+	"server-time":  "",
 }
 
@@ -89,8 +89,8 @@
 	logger := &prefixLogger{srv.Logger, fmt.Sprintf("downstream %q: ", netConn.RemoteAddr())}
 	dc := &downstreamConn{
-		conn: *newConn(srv, netConn, logger),
-		id:   id,
+		conn:          *newConn(srv, netConn, logger),
+		id:            id,
 		supportedCaps: make(map[string]string),
-		caps: make(map[string]bool),
+		caps:          make(map[string]bool),
 	}
 	dc.hostname = netConn.RemoteAddr().String()
@@ -459,5 +459,5 @@
 		for k, v := range dc.supportedCaps {
 			if dc.capVersion >= 302 && v != "" {
-				caps = append(caps, k + "=" + v)
+				caps = append(caps, k+"="+v)
 			} else {
 				caps = append(caps, k)
@@ -594,4 +594,17 @@
 		Params:  []string{replyTo, "DEL", name},
 	})
+}
+
+func (dc *downstreamConn) updateSupportedCaps() {
+	awayNotifySupported := true
+	dc.forEachUpstream(func(uc *upstreamConn) {
+		awayNotifySupported = awayNotifySupported && uc.awayNotifySupported
+	})
+
+	if awayNotifySupported {
+		dc.setSupportedCap("away-notify", "")
+	} else {
+		dc.unsetSupportedCap("away-notify")
+	}
 }
 
Index: /trunk/upstream.go
===================================================================
--- /trunk/upstream.go	(revision 275)
+++ /trunk/upstream.go	(revision 276)
@@ -47,11 +47,12 @@
 	modes      userModes
 	channels   map[string]*upstreamChannel
-	caps       map[string]string
+	caps       map[string]string // available capabilities
 	batches    map[string]batch
 	away       bool
 
-	tagsSupported   bool
-	labelsSupported bool
-	nextLabelID     uint64
+	tagsSupported       bool
+	awayNotifySupported bool
+	labelsSupported     bool
+	nextLabelID         uint64
 
 	saslClient  sasl.Client
@@ -318,5 +319,5 @@
 
 			requestCaps := make([]string, 0, 16)
-			for _, c := range []string{"message-tags", "batch", "labeled-response", "server-time"} {
+			for _, c := range []string{"message-tags", "batch", "labeled-response", "server-time", "away-notify"} {
 				if _, ok := uc.caps[c]; ok {
 					requestCaps = append(requestCaps, c)
@@ -450,4 +451,8 @@
 		uc.registered = true
 		uc.logger.Printf("connection registered")
+
+		uc.forEachDownstream(func(dc *downstreamConn) {
+			dc.updateSupportedCaps()
+		})
 
 		for _, ch := range uc.network.channels {
@@ -1149,4 +1154,19 @@
 			})
 		})
+	case "AWAY":
+		if msg.Prefix == nil {
+			return fmt.Errorf("expected a prefix")
+		}
+
+		uc.forEachDownstream(func(dc *downstreamConn) {
+			if !dc.caps["away-notify"] {
+				return
+			}
+			dc.SendMessage(&irc.Message{
+				Prefix:  dc.marshalUserPrefix(uc.network, msg.Prefix),
+				Command: "AWAY",
+				Params:  msg.Params,
+			})
+		})
 	case "TAGMSG":
 		// TODO: relay to downstream connections that accept message-tags
@@ -1263,5 +1283,4 @@
 
 func (uc *upstreamConn) handleCapAck(name string, ok bool) error {
-	auth := &uc.network.SASL
 	switch name {
 	case "sasl":
@@ -1271,4 +1290,5 @@
 		}
 
+		auth := &uc.network.SASL
 		switch auth.Mechanism {
 		case "PLAIN":
@@ -1287,4 +1307,6 @@
 	case "labeled-response":
 		uc.labelsSupported = ok
+	case "away-notify":
+		uc.awayNotifySupported = ok
 	case "batch", "server-time":
 		// Nothing to do
Index: /trunk/user.go
===================================================================
--- /trunk/user.go	(revision 275)
+++ /trunk/user.go	(revision 276)
@@ -256,4 +256,5 @@
 
 			uc.forEachDownstream(func(dc *downstreamConn) {
+				dc.updateSupportedCaps()
 				sendServiceNOTICE(dc, fmt.Sprintf("connected to %s", uc.network.GetName()))
 			})
@@ -271,4 +272,8 @@
 
 			uc.endPendingLISTs(true)
+
+			uc.forEachDownstream(func(dc *downstreamConn) {
+				dc.updateSupportedCaps()
+			})
 
 			if uc.network.lastError == nil {
@@ -315,4 +320,6 @@
 				uc.updateAway()
 			})
+
+			dc.updateSupportedCaps()
 		case eventDownstreamDisconnected:
 			dc := e.dc
