3
3
package agentssh
4
4
5
5
import (
6
+ "errors"
6
7
"fmt"
7
8
"os"
8
9
@@ -11,24 +12,33 @@ 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
+ tabs ,err := netstat .TCPSocks (acceptFn )
19
+ tabs6 ,err6 := netstat .TCP6Socks (acceptFn )
20
+
21
+ // Only return the error if the other method found nothing.
22
+ if (err != nil && len (tabs6 )== 0 )|| (err6 != nil && len (tabs )== 0 ) {
23
+ return "" ,xerrors .Errorf ("inspect port %d: %w" ,port ,errors .Join (err ,err6 ))
22
24
}
23
25
24
- // Defensive check.
25
- if tabs [0 ].Process == nil {
26
+ var proc * netstat.Process
27
+ if len (tabs )> 0 {
28
+ proc = tabs [0 ].Process
29
+ }else if len (tabs6 )> 0 {
30
+ proc = tabs6 [0 ].Process
31
+ }
32
+ if proc == nil {
33
+ // Either nothing is listening on this port or we were unable to read the
34
+ // process details (permission issues reading /proc/$pid/* potentially).
35
+ // Or, perhaps /proc/net/tcp{,6} is not listing the port for some reason.
26
36
return "" ,nil
27
37
}
28
38
29
39
// The process name provided by go-netstat does not include the full command
30
40
// line so grab that instead.
31
- pid := tabs [ 0 ]. Process .Pid
41
+ pid := proc .Pid
32
42
data ,err := os .ReadFile (fmt .Sprintf ("/proc/%d/cmdline" ,pid ))
33
43
if err != nil {
34
44
return "" ,xerrors .Errorf ("read /proc/%d/cmdline: %w" ,pid ,err )