Skip to content

Commit 750e2c7

Browse files
authoredOct 29, 2024
Fetch all ip addresses in a single stdlib call (#246)
When fetching ip addresses for the host, we fetch all the network interfaces, and then ip addresses for each interface. The latter call is surprisingly expensive on unix, as it involves opening a netlink socket, sending a request for routing information, and receiving and parsing the response. If the host has a lot of network interfaces, this can eat surprising amounts of memory - I got in the order of 10 MB on a Kubernetes Node with 100 Pods. See elastic/elastic-agent#5835 (comment) for some heap profiles from elastic-agent. Instead, get all the addresses in a single stdlib call. We don't actually care about which interface each ip address is attached to, we just want all of them. I've tested this in the real world scenario discussed in elastic/elastic-agent#5835, not sure how to include a self-contained test in this repo.
1 parent b4a498b commit 750e2c7

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed
 

‎.changelog/246.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
Fetch all IP addresses in a single stdlib call
3+
```

‎providers/shared/network.go

+12-9
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,20 @@ func Network() (ips, macs []string, err error) {
2727
return nil, nil, err
2828
}
2929

30-
ips = make([]string, 0, len(ifcs))
30+
// This function fetches all the addresses in a single syscall. Fetching addresses individually for each interface
31+
// can be expensive when the host has a lot of interfaces. This usually happens when the host is doing virtualized
32+
// networking for guests, in Kubernetes for example.
33+
addrs, err := net.InterfaceAddrs()
34+
if err != nil {
35+
return nil, nil, err
36+
}
37+
ips = make([]string, 0, len(addrs))
38+
for _, addr := range addrs {
39+
ips = append(ips, addr.String())
40+
}
41+
3142
macs = make([]string, 0, len(ifcs))
3243
for _, ifc := range ifcs {
33-
addrs, err := ifc.Addrs()
34-
if err != nil {
35-
return nil, nil, err
36-
}
37-
for _, addr := range addrs {
38-
ips = append(ips, addr.String())
39-
}
40-
4144
mac := ifc.HardwareAddr.String()
4245
if mac != "" {
4346
macs = append(macs, mac)

0 commit comments

Comments
 (0)
Failed to load comments.