|
|
|
@ -392,7 +392,7 @@ func Connections(kind string) ([]ConnectionStat, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
|
|
|
|
return ConnectionsPid(kind, 0)
|
|
|
|
|
return ConnectionsPidWithContext(ctx, kind, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return a list of network connections opened returning at most `max`
|
|
|
|
@ -402,7 +402,7 @@ func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
|
|
|
|
return ConnectionsPidMax(kind, 0, max)
|
|
|
|
|
return ConnectionsPidMaxWithContext(ctx, kind, 0, max)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return a list of network connections opened, omitting `Uids`.
|
|
|
|
@ -463,7 +463,7 @@ func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, p
|
|
|
|
|
var err error
|
|
|
|
|
var inodes map[string][]inodeMap
|
|
|
|
|
if pid == 0 {
|
|
|
|
|
inodes, err = getProcInodesAll(root, max)
|
|
|
|
|
inodes, err = getProcInodesAllWithContext(ctx, root, max)
|
|
|
|
|
} else {
|
|
|
|
|
inodes, err = getProcInodes(root, pid, max)
|
|
|
|
|
if len(inodes) == 0 {
|
|
|
|
@ -474,10 +474,14 @@ func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, p
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("cound not get pid(s), %d: %w", pid, err)
|
|
|
|
|
}
|
|
|
|
|
return statsFromInodes(root, pid, tmap, inodes, skipUids)
|
|
|
|
|
return statsFromInodesWithContext(ctx, root, pid, tmap, inodes, skipUids)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func statsFromInodes(root string, pid int32, tmap []netConnectionKindType, inodes map[string][]inodeMap, skipUids bool) ([]ConnectionStat, error) {
|
|
|
|
|
return statsFromInodesWithContext(context.Background(), root, pid, tmap, inodes, skipUids)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func statsFromInodesWithContext(ctx context.Context, root string, pid int32, tmap []netConnectionKindType, inodes map[string][]inodeMap, skipUids bool) ([]ConnectionStat, error) {
|
|
|
|
|
dupCheckMap := make(map[string]struct{})
|
|
|
|
|
var ret []ConnectionStat
|
|
|
|
|
|
|
|
|
@ -493,7 +497,7 @@ func statsFromInodes(root string, pid int32, tmap []netConnectionKindType, inode
|
|
|
|
|
}
|
|
|
|
|
switch t.family {
|
|
|
|
|
case syscall.AF_INET, syscall.AF_INET6:
|
|
|
|
|
ls, err = processInet(path, t, inodes, pid)
|
|
|
|
|
ls, err = processInetWithContext(ctx, path, t, inodes, pid)
|
|
|
|
|
case syscall.AF_UNIX:
|
|
|
|
|
ls, err = processUnix(path, t, inodes, pid)
|
|
|
|
|
}
|
|
|
|
@ -666,7 +670,11 @@ func (p *process) fillFromStatus() error {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getProcInodesAll(root string, max int) (map[string][]inodeMap, error) {
|
|
|
|
|
pids, err := Pids()
|
|
|
|
|
return getProcInodesAllWithContext(context.Background(), root, max)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getProcInodesAllWithContext(ctx context.Context, root string, max int) (map[string][]inodeMap, error) {
|
|
|
|
|
pids, err := PidsWithContext(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -695,6 +703,10 @@ func getProcInodesAll(root string, max int) (map[string][]inodeMap, error) {
|
|
|
|
|
// "0500000A:0016" -> "10.0.0.5", 22
|
|
|
|
|
// "0085002452100113070057A13F025401:0035" -> "2400:8500:1301:1052:a157:7:154:23f", 53
|
|
|
|
|
func decodeAddress(family uint32, src string) (Addr, error) {
|
|
|
|
|
return decodeAddressWithContext(context.Background(), family, src)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func decodeAddressWithContext(ctx context.Context, family uint32, src string) (Addr, error) {
|
|
|
|
|
t := strings.Split(src, ":")
|
|
|
|
|
if len(t) != 2 {
|
|
|
|
|
return Addr{}, fmt.Errorf("does not contain port, %s", src)
|
|
|
|
@ -711,9 +723,9 @@ func decodeAddress(family uint32, src string) (Addr, error) {
|
|
|
|
|
var ip net.IP
|
|
|
|
|
// Assumes this is little_endian
|
|
|
|
|
if family == syscall.AF_INET {
|
|
|
|
|
ip = net.IP(Reverse(decoded))
|
|
|
|
|
ip = net.IP(ReverseWithContext(ctx, decoded))
|
|
|
|
|
} else { // IPv6
|
|
|
|
|
ip, err = parseIPv6HexString(decoded)
|
|
|
|
|
ip, err = parseIPv6HexStringWithContext(ctx, decoded)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return Addr{}, err
|
|
|
|
|
}
|
|
|
|
@ -738,19 +750,27 @@ func ReverseWithContext(ctx context.Context, s []byte) []byte {
|
|
|
|
|
|
|
|
|
|
// parseIPv6HexString parse array of bytes to IPv6 string
|
|
|
|
|
func parseIPv6HexString(src []byte) (net.IP, error) {
|
|
|
|
|
return parseIPv6HexStringWithContext(context.Background(), src)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseIPv6HexStringWithContext(ctx context.Context, src []byte) (net.IP, error) {
|
|
|
|
|
if len(src) != 16 {
|
|
|
|
|
return nil, fmt.Errorf("invalid IPv6 string")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf := make([]byte, 0, 16)
|
|
|
|
|
for i := 0; i < len(src); i += 4 {
|
|
|
|
|
r := Reverse(src[i : i+4])
|
|
|
|
|
r := ReverseWithContext(ctx, src[i:i+4])
|
|
|
|
|
buf = append(buf, r...)
|
|
|
|
|
}
|
|
|
|
|
return net.IP(buf), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func processInet(file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) {
|
|
|
|
|
return processInetWithContext(context.Background(), file, kind, inodes, filterPid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func processInetWithContext(ctx context.Context, file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) {
|
|
|
|
|
if strings.HasSuffix(file, "6") && !common.PathExists(file) {
|
|
|
|
|
// IPv6 not supported, return empty.
|
|
|
|
|
return []connTmp{}, nil
|
|
|
|
@ -793,11 +813,11 @@ func processInet(file string, kind netConnectionKindType, inodes map[string][]in
|
|
|
|
|
} else {
|
|
|
|
|
status = "NONE"
|
|
|
|
|
}
|
|
|
|
|
la, err := decodeAddress(kind.family, laddr)
|
|
|
|
|
la, err := decodeAddressWithContext(ctx, kind.family, laddr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
ra, err := decodeAddress(kind.family, raddr)
|
|
|
|
|
ra, err := decodeAddressWithContext(ctx, kind.family, raddr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|