|
@@ -9,6 +9,7 @@ import (
|
9
|
9
|
"net"
|
10
|
10
|
"regexp"
|
11
|
11
|
"strings"
|
|
12
|
+ "syscall"
|
12
|
13
|
)
|
13
|
14
|
|
14
|
15
|
var (
|
|
@@ -195,10 +196,24 @@ func HandleXForwardedFor(remoteAddr string, xForwardedFor string, whitelist []ne
|
195
|
196
|
return
|
196
|
197
|
}
|
197
|
198
|
|
198
|
|
-func DescribeConn(conn net.Conn) string {
|
199
|
|
- // XXX for unix domain sockets, this is not informative enough for an operator
|
200
|
|
- // to determine who holds the other side of the connection. there seems to be
|
201
|
|
- // no way to get either the correct file descriptor of the connection, or the
|
202
|
|
- // udiag_ino from `man 7 sock_diag`. maybe there's something else we can do?
|
203
|
|
- return fmt.Sprintf("%s <-> %s", conn.LocalAddr().String(), conn.RemoteAddr().String())
|
|
199
|
+// Output a description of a connection that can identify it to other systems
|
|
200
|
+// administration tools.
|
|
201
|
+func DescribeConn(c net.Conn) (description string) {
|
|
202
|
+ description = "<error>"
|
|
203
|
+ switch conn := c.(type) {
|
|
204
|
+ case *net.UnixConn:
|
|
205
|
+ f, err := conn.File()
|
|
206
|
+ if err != nil {
|
|
207
|
+ return
|
|
208
|
+ }
|
|
209
|
+ defer f.Close()
|
|
210
|
+ ucred, err := syscall.GetsockoptUcred(int(f.Fd()), syscall.SOL_SOCKET, syscall.SO_PEERCRED)
|
|
211
|
+ if err != nil {
|
|
212
|
+ return
|
|
213
|
+ }
|
|
214
|
+ return fmt.Sprintf("%s <-> %s [pid=%d, uid=%d]", conn.LocalAddr().String(), conn.RemoteAddr().String(), ucred.Pid, ucred.Uid)
|
|
215
|
+ default:
|
|
216
|
+ // *net.TCPConn or *tls.Conn
|
|
217
|
+ return fmt.Sprintf("%s <-> %s", conn.LocalAddr().String(), conn.RemoteAddr().String())
|
|
218
|
+ }
|
204
|
219
|
}
|