diff --git a/irc/utils/net.go b/irc/utils/net.go index 3c3a55f1..c323c2dc 100644 --- a/irc/utils/net.go +++ b/irc/utils/net.go @@ -9,6 +9,7 @@ import ( "net" "regexp" "strings" + "syscall" ) var ( @@ -195,10 +196,24 @@ func HandleXForwardedFor(remoteAddr string, xForwardedFor string, whitelist []ne return } -func DescribeConn(conn net.Conn) string { - // XXX for unix domain sockets, this is not informative enough for an operator - // to determine who holds the other side of the connection. there seems to be - // no way to get either the correct file descriptor of the connection, or the - // udiag_ino from `man 7 sock_diag`. maybe there's something else we can do? - return fmt.Sprintf("%s <-> %s", conn.LocalAddr().String(), conn.RemoteAddr().String()) +// Output a description of a connection that can identify it to other systems +// administration tools. +func DescribeConn(c net.Conn) (description string) { + description = "" + switch conn := c.(type) { + case *net.UnixConn: + f, err := conn.File() + if err != nil { + return + } + defer f.Close() + ucred, err := syscall.GetsockoptUcred(int(f.Fd()), syscall.SOL_SOCKET, syscall.SO_PEERCRED) + if err != nil { + return + } + return fmt.Sprintf("%s <-> %s [pid=%d, uid=%d]", conn.LocalAddr().String(), conn.RemoteAddr().String(), ucred.Pid, ucred.Uid) + default: + // *net.TCPConn or *tls.Conn + return fmt.Sprintf("%s <-> %s", conn.LocalAddr().String(), conn.RemoteAddr().String()) + } }