Skip to content

Commit 411373f

Browse files
authored
Merge pull request #12 from nberlee/fix-concurrency
fix: potentential conurrency issue when running as a module
2 parents a71ff7c + 1e6ac37 commit 411373f

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ jobs:
2222
run: go build -v ./...
2323

2424
- name: Test
25-
run: go test -v ./...
25+
run: go test -race -v ./...

netstat/export_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package netstat
22

3+
var pd = newProcessData()
4+
35
var (
46
// Exported for testing
57
ParseAddr = parseAddr
68
ParseIPv4 = parseIPv4
79
ParseIPv6 = parseIPv6
8-
ParseSockTab = parseSockTab
9-
OpenFileStream = openFileStream
10+
ParseSockTab = pd.parseSockTab
11+
OpenFileStream = pd.openFileStream
1012
)

netstat/netstat_linux.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,17 @@ const (
5050
Closing
5151
)
5252

53-
var fdProcess = make(map[uint64]*common.Process)
54-
var pidNetNS map[uint32]string
53+
type processData struct {
54+
fdProcess map[uint64]*common.Process
55+
pidNetNS map[uint32]string
56+
}
57+
58+
func newProcessData() *processData {
59+
return &processData{
60+
fdProcess: make(map[uint64]*common.Process),
61+
pidNetNS: make(map[uint32]string),
62+
}
63+
}
5564

5665
var skStates = [...]string{
5766
"UNKNOWN",
@@ -137,7 +146,7 @@ func parseAddr(s string) (*SockEndpoint, error) {
137146
return &SockEndpoint{IP: ip, Port: uint16(v)}, nil
138147
}
139148

140-
func parseSockTab(reader io.Reader, accept AcceptFn, transport string, podPid uint32) ([]SockTabEntry, error) {
149+
func (pd *processData) parseSockTab(reader io.Reader, accept AcceptFn, transport string, podPid uint32) ([]SockTabEntry, error) {
141150
scanner := bufio.NewScanner(reader)
142151
scanner.Scan()
143152

@@ -177,13 +186,13 @@ func parseSockTab(reader io.Reader, accept AcceptFn, transport string, podPid ui
177186
}
178187
entry.Transport = transport
179188
if podPid != 0 {
180-
if netNsName, ok := pidNetNS[podPid]; ok {
189+
if netNsName, ok := pd.pidNetNS[podPid]; ok {
181190
entry.NetNS = netNsName
182191
} else {
183192
entry.NetNS = strconv.Itoa(int(podPid))
184193
}
185194
}
186-
entry.Process = fdProcess[entry.Inode]
195+
entry.Process = pd.fdProcess[entry.Inode]
187196
if accept(&entry) {
188197
sockTab = append(sockTab, entry)
189198
}
@@ -198,15 +207,17 @@ func parseSockTab(reader io.Reader, accept AcceptFn, transport string, podPid ui
198207
func Netstat(ctx context.Context, feature EnableFeatures, fn AcceptFn) ([]SockTabEntry, error) {
199208
var err error
200209

201-
pids, err := mergePids(feature)
210+
pd := newProcessData()
211+
212+
pids, err := pd.mergePids(feature)
202213
if err != nil {
203214
return nil, err
204215
}
205216

206217
files := procFiles(feature, pids)
207218

208219
if feature.PID {
209-
fdProcess, err = processes.GetProcessFDs(ctx)
220+
pd.fdProcess, err = processes.GetProcessFDs(ctx)
210221
if err != nil {
211222
return nil, err
212223
}
@@ -226,7 +237,7 @@ func Netstat(ctx context.Context, feature EnableFeatures, fn AcceptFn) ([]SockTa
226237
chs[i] <- []SockTabEntry{}
227238
return
228239
default:
229-
tabs, err := openFileStream(file, fn)
240+
tabs, err := pd.openFileStream(file, fn)
230241
if err != nil {
231242
// Send an empty slice if there was an error.
232243
chs[i] <- []SockTabEntry{}
@@ -252,7 +263,7 @@ func Netstat(ctx context.Context, feature EnableFeatures, fn AcceptFn) ([]SockTa
252263
return combinedTabs, nil
253264
}
254265

255-
func mergePids(feature EnableFeatures) (pids []string, err error) {
266+
func (pd *processData) mergePids(feature EnableFeatures) (pids []string, err error) {
256267
if feature.AllNetNs {
257268
netNsName, err := netns.GetNetNSNames()
258269
if err != nil {
@@ -267,17 +278,16 @@ func mergePids(feature EnableFeatures) (pids []string, err error) {
267278
feature.NetNsPids = []uint32{}
268279
}
269280

270-
pidNetNS = map[uint32]string{}
271281
if len(feature.NetNsName) > 0 {
272-
pidNetNS = *netns.GetNetNsPids(feature.NetNsName)
282+
pd.pidNetNS = *netns.GetNetNsPids(feature.NetNsName)
273283
}
274284

275285
hostNetNsIndex := 0
276286
if !feature.NoHostNetwork {
277287
hostNetNsIndex = 1
278288
}
279289

280-
lengthPids := len(pidNetNS) + len(feature.NetNsPids) + hostNetNsIndex
290+
lengthPids := len(pd.pidNetNS) + len(feature.NetNsPids) + hostNetNsIndex
281291
pids = make([]string, lengthPids)
282292

283293
if !feature.NoHostNetwork {
@@ -286,7 +296,7 @@ func mergePids(feature EnableFeatures) (pids []string, err error) {
286296

287297
netNsNameIndex := 0
288298

289-
for pid := range pidNetNS {
299+
for pid := range pd.pidNetNS {
290300
pids[netNsNameIndex+hostNetNsIndex] = strconv.Itoa(int(pid))
291301
netNsNameIndex++
292302
}
@@ -329,7 +339,7 @@ func procFiles(feature EnableFeatures, pids []string) (files []string) {
329339
return files
330340
}
331341

332-
func openFileStream(file string, fn AcceptFn) ([]SockTabEntry, error) {
342+
func (pd *processData) openFileStream(file string, fn AcceptFn) ([]SockTabEntry, error) {
333343
f, err := os.Open(file)
334344
if err != nil {
335345
return nil, err
@@ -338,7 +348,7 @@ func openFileStream(file string, fn AcceptFn) ([]SockTabEntry, error) {
338348
_, transport := path.Split(file)
339349
podPid, _ := strconv.ParseUint(strings.Split(file, "/")[2], 10, 32)
340350

341-
tabs, err := parseSockTab(f, fn, transport, uint32(podPid))
351+
tabs, err := pd.parseSockTab(f, fn, transport, uint32(podPid))
342352
if err != nil {
343353
return nil, err
344354
}

0 commit comments

Comments
 (0)