Skip to content

Commit f94e8ec

Browse files
authored
Merge pull request #1 from xNaCly/main
refactor: cache inode->pid lookup via map on function startup
2 parents 2859ec7 + bbd7594 commit f94e8ec

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

linux-open-ports.go

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import (
77
"path/filepath"
88
"strconv"
99
"strings"
10+
"unicode"
1011
)
1112

1213
type OpenPort struct {
1314
Protocol string
1415
Port int
15-
PID int
16+
PID string
1617
}
1718

1819
func GetOpenPorts() ([]OpenPort, error) {
@@ -24,6 +25,8 @@ func GetOpenPorts() ([]OpenPort, error) {
2425
"udp": {"/proc/net/udp", "/proc/net/udp6"},
2526
}
2627

28+
cachedInodePIDMap := inodePIDMap()
29+
2730
for protocol, files := range protocolFiles {
2831
for _, filePath := range files {
2932
file, err := os.Open(filePath)
@@ -54,7 +57,11 @@ func GetOpenPorts() ([]OpenPort, error) {
5457
continue
5558
}
5659

57-
pid := findPIDByInode(inode)
60+
pid, ok := cachedInodePIDMap[inode]
61+
if !ok {
62+
continue
63+
}
64+
5865
portKey := fmt.Sprintf("%s/%d", protocol, port)
5966
if !uniquePorts[portKey] {
6067
openPorts = append(openPorts, OpenPort{
@@ -71,33 +78,32 @@ func GetOpenPorts() ([]OpenPort, error) {
7178
return openPorts, nil
7279
}
7380

74-
func findPIDByInode(inode string) int {
81+
func inodePIDMap() map[string]string {
82+
m := map[string]string{}
7583
procDirs, _ := os.ReadDir("/proc")
7684
for _, procDir := range procDirs {
77-
if !procDir.IsDir() || !isNumeric(procDir.Name()) {
85+
pid := procDir.Name()
86+
if !procDir.IsDir() && !unicode.IsDigit(rune(pid[0])) {
7887
continue
7988
}
8089

81-
pid := procDir.Name()
8290
fdDir := filepath.Join("/proc", pid, "fd")
8391
fdFiles, err := os.ReadDir(fdDir)
8492
if err != nil {
8593
continue
8694
}
8795

8896
for _, fdFile := range fdFiles {
89-
fdPath := filepath.Join(fdDir, fdFile.Name())
90-
link, err := os.Readlink(fdPath)
91-
if err == nil && strings.Contains(link, fmt.Sprintf("socket:[%s]", inode)) {
92-
pidInt, _ := strconv.Atoi(pid)
93-
return pidInt
97+
path := filepath.Join(fdDir, fdFile.Name())
98+
linkName, err := os.Readlink(path)
99+
if err != nil {
100+
continue
101+
}
102+
if strings.Contains(linkName, "socket") {
103+
inode := linkName[8 : len(linkName)-1]
104+
m[inode] = pid
94105
}
95106
}
96107
}
97-
return -1
98-
}
99-
100-
func isNumeric(s string) bool {
101-
_, err := strconv.Atoi(s)
102-
return err == nil
108+
return m
103109
}

0 commit comments

Comments
 (0)