[net][linux]: get Pid and Fd from inode in netlink.

feature/add_linux_netlink
shirou 5 years ago
parent 651c992042
commit 28dc7e6146

@ -6,6 +6,7 @@ package net
import (
"context"
"fmt"
"strconv"
"sync"
"syscall"
@ -22,17 +23,54 @@ func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, p
var err error
var inodes map[string][]inodeMap
if pid == 0 {
return connectionsNetLink(tmap)
inodes, err = getProcInodesAll(root, max)
} else {
inodes, err = getProcInodes(root, pid, max)
}
inodes, err = getProcInodes(root, pid, max)
if len(inodes) == 0 {
// no connection for the pid
// no inode for the pid
return []ConnectionStat{}, nil
}
if err != nil {
return nil, fmt.Errorf("cound not get pid(s), %d: %s", pid, err)
}
return statsFromInodes(root, pid, tmap, inodes, skipUids)
return connectionsNetLink(tmap, inodes)
}
func connectionsNetLink(kinds []netConnectionKindType, inodes map[string][]inodeMap) ([]ConnectionStat, error) {
wait := &sync.WaitGroup{}
reply := make([][]ConnectionStat, len(kinds))
var retErrr error
for i, kind := range kinds {
wait.Add(1)
if kind.family == syscall.AF_UNIX {
go getUnixConnections(wait, i, reply)
} else {
go getInetConnections(wait, i, kind, reply)
}
}
wait.Wait()
ret := make([]ConnectionStat, 0)
for i := range kinds {
for _, cs := range reply[i] {
iss, exists := inodes[strconv.Itoa(int(cs.Fd))]
if exists {
for _, is := range iss {
cs.Pid = is.pid
cs.Fd = is.fd
}
} else {
cs.Fd = 0
}
ret = append(ret, cs)
}
}
return ret, retErrr
}
func getInetConnections(wait *sync.WaitGroup, i int, k netConnectionKindType, reply [][]ConnectionStat) {
@ -52,7 +90,7 @@ func getInetConnections(wait *sync.WaitGroup, i int, k netConnectionKindType, re
Status: netlink.TCPState(msg.State).String(),
Uids: []int32{int32(msg.UID)},
// Pid: msg.Pid,
// Fd: diag.Inode,
Fd: msg.Inode,
}
t[i] = conn
}
@ -72,35 +110,12 @@ func getUnixConnections(wait *sync.WaitGroup, i int, reply [][]ConnectionStat) {
Family: uint32(msg.Family),
Status: netlink.TCPState(msg.State).String(),
Uids: []int32{},
Laddr: Addr{
Laddr: Addr{
IP: msg.Path,
},
Fd: msg.Inode,
}
t[i] = conn
}
reply[i] = t
}
func connectionsNetLink(kinds []netConnectionKindType) ([]ConnectionStat, error) {
wait := &sync.WaitGroup{}
reply := make([][]ConnectionStat, len(kinds))
var retErrr error
for i, kind := range kinds {
wait.Add(1)
if kind.family == syscall.AF_UNIX {
go getUnixConnections(wait, i, reply)
} else {
go getInetConnections(wait, i, kind, reply)
}
}
wait.Wait()
ret := make([]ConnectionStat, 0)
for i := range kinds {
ret = append(ret, reply[i]...)
}
return ret, retErrr
}

@ -22,10 +22,10 @@ func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, p
inodes, err = getProcInodesAll(root, max)
} else {
inodes, err = getProcInodes(root, pid, max)
if len(inodes) == 0 {
// no connection for the pid
return []ConnectionStat{}, nil
}
}
if len(inodes) == 0 {
// no connection for the pid
return []ConnectionStat{}, nil
}
if err != nil {
return nil, fmt.Errorf("cound not get pid(s), %d: %s", pid, err)

Loading…
Cancel
Save