Merge pull request #2114 from weaveworks/1972-non-established-proc-conns

Report persistent connections in states other than ESTABLISHED
This commit is contained in:
Alfonso Acosta
2017-01-17 10:45:53 +01:00
committed by GitHub
4 changed files with 28 additions and 20 deletions
+17 -13
View File
@@ -5,22 +5,23 @@ import (
"net"
)
// Used to check whether we are parsing a header line
var slHeader = []byte("sl")
// ProcNet is an iterator to parse /proc/net/tcp{,6} files.
type ProcNet struct {
b []byte
c Connection
wantedState uint
bytesLocal, bytesRemote [16]byte
seen map[uint64]struct{}
}
// NewProcNet gives a new ProcNet parser.
func NewProcNet(b []byte, wantedState uint) *ProcNet {
func NewProcNet(b []byte) *ProcNet {
return &ProcNet{
b: b,
c: Connection{},
wantedState: wantedState,
seen: map[uint64]struct{}{},
b: b,
c: Connection{},
seen: map[uint64]struct{}{},
}
}
@@ -33,20 +34,23 @@ again:
}
b := p.b
if p.b[2] == 's' {
var (
sl, local, remote, state, inode []byte
)
sl, b = nextField(b) // 'sl' column
if bytes.Equal(sl, slHeader) {
// Skip header
p.b = nextLine(b)
goto again
}
var (
local, remote, state, inode []byte
)
_, b = nextField(b) // 'sl' column
local, b = nextField(b)
remote, b = nextField(b)
state, b = nextField(b)
if parseHex(state) != p.wantedState {
switch parseHex(state) {
// Only process established or half-closed connections
case tcpEstablished, tcpFinWait1, tcpFinWait2, tcpCloseWait:
default:
p.b = nextLine(b)
goto again
}
@@ -13,7 +13,7 @@ func TestProcNet(t *testing.T) {
2: 0100007F:0019 00000000:0000 01 00000000:00000000 00:00000000 00000000 0 0 10550 1 ffff8800a729b780 100 0 0 10 0
3: A12CF62E:E4D7 57FC1EC0:01BB 01 00000000:00000000 02:000006FA 00000000 1000 0 639474 2 ffff88007e75a740 48 4 26 10 -1
`
p := NewProcNet([]byte(testString), tcpEstablished)
p := NewProcNet([]byte(testString))
expected := []Connection{
{
LocalAddress: net.IP([]byte{0, 0, 0, 0}),
@@ -59,12 +59,12 @@ func TestProcNet(t *testing.T) {
func TestTransport6(t *testing.T) {
// Abridged copy of my /proc/net/tcp6
testString := ` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout Inode
testString := ` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout Inode
0: 00000000000000000000000000000000:19C8 00000000000000000000000000000000:0000 01 00000000:00000000 00:00000000 00000000 0 0 23661201 1 ffff880103fb4800 100 0 0 10 -1
8: 4500032000BE692B8AE31EBD919D9D10:D61C 5014002A080805400000000015100000:01BB 01 00000000:00000000 02:00000045 00000000 1000 0 36856710 2 ffff88010b796080 22 4 30 8 7
`
p := NewProcNet([]byte(testString), tcpEstablished)
p := NewProcNet([]byte(testString))
expected := []Connection{
{
// state: 10,
@@ -114,7 +114,7 @@ func TestTransportNonsense(t *testing.T) {
0: 00000000:A6C0 00000000:0000 01 000000
broken line
`
p := NewProcNet([]byte(testString), tcpEstablished)
p := NewProcNet([]byte(testString))
expected := []Connection{
{
LocalAddress: net.IP([]byte{0, 0, 0, 0}),
@@ -142,7 +142,7 @@ func TestProcNetFiltersDuplicates(t *testing.T) {
0: 00000000:A6C0 00000000:0000 01 00000000:00000000 00:00000000 00000000 105 0 5107 1 ffff8800a6aaf040 100 0 0 10 0
1: 00000000:A6C0 00000000:0000 01 00000000:00000000 00:00000000 00000000 105 0 5107 1 ffff8800a6aaf040 100 0 0 10 0
`
p := NewProcNet([]byte(testString), tcpEstablished)
p := NewProcNet([]byte(testString))
expected := Connection{
LocalAddress: net.IP([]byte{0, 0, 0, 0}),
LocalPort: 0xa6c0,
+5 -1
View File
@@ -8,7 +8,11 @@ import (
)
const (
tcpEstablished = 1 // according to /include/net/tcp_states.h
// according to /include/net/tcp_states.h
tcpEstablished = 1
tcpFinWait1 = 4
tcpFinWait2 = 5
tcpCloseWait = 8
)
// Connection is a (TCP) connection. The Proc struct might not be filled in.
+1 -1
View File
@@ -61,7 +61,7 @@ func (s *linuxScanner) Connections(processes bool) (ConnIter, error) {
}
return &pnConnIter{
pn: NewProcNet(buf.Bytes(), tcpEstablished),
pn: NewProcNet(buf.Bytes()),
buf: buf,
procs: procs,
}, nil