3
3
package agentssh
4
4
5
5
import (
6
+ "errors"
6
7
"fmt"
7
8
"os"
8
9
@@ -11,24 +12,37 @@ import (
11
12
)
12
13
13
14
func getListeningPortProcessCmdline (port uint32 ) (string , error ) {
14
- tabs , err := netstat . TCPSocks ( func (s * netstat.SockTabEntry ) bool {
15
+ acceptFn := func (s * netstat.SockTabEntry ) bool {
15
16
return s .LocalAddr != nil && uint32 (s .LocalAddr .Port ) == port
16
- })
17
- if err != nil {
18
- return "" , xerrors .Errorf ("inspect port %d: %w" , port , err )
19
17
}
20
- if len (tabs ) == 0 {
21
- return "" , nil
18
+ tabs4 , err4 := netstat .TCPSocks (acceptFn )
19
+ tabs6 , err6 := netstat .TCP6Socks (acceptFn )
20
+
21
+ // In the common case, we want to check ipv4 listening addresses. If this
22
+ // fails, we should return an error. We also need to check ipv6. The
23
+ // assumption is, if we have an err4, and 0 ipv6 addresses listed, then we are
24
+ // interested in the err4 (and vice versa). So return both errors (at least 1
25
+ // is non-nil) if the other list is empty.
26
+ if (err4 != nil && len (tabs6 ) == 0 ) || (err6 != nil && len (tabs4 ) == 0 ) {
27
+ return "" , xerrors .Errorf ("inspect port %d: %w" , port , errors .Join (err4 , err6 ))
22
28
}
23
29
24
- // Defensive check.
25
- if tabs [0 ].Process == nil {
30
+ var proc * netstat.Process
31
+ if len (tabs4 ) > 0 {
32
+ proc = tabs4 [0 ].Process
33
+ } else if len (tabs6 ) > 0 {
34
+ proc = tabs6 [0 ].Process
35
+ }
36
+ if proc == nil {
37
+ // Either nothing is listening on this port or we were unable to read the
38
+ // process details (permission issues reading /proc/$pid/* potentially).
39
+ // Or, perhaps /proc/net/tcp{,6} is not listing the port for some reason.
26
40
return "" , nil
27
41
}
28
42
29
43
// The process name provided by go-netstat does not include the full command
30
44
// line so grab that instead.
31
- pid := tabs [ 0 ]. Process .Pid
45
+ pid := proc .Pid
32
46
data , err := os .ReadFile (fmt .Sprintf ("/proc/%d/cmdline" , pid ))
33
47
if err != nil {
34
48
return "" , xerrors .Errorf ("read /proc/%d/cmdline: %w" , pid , err )
0 commit comments