From 181a54812206dea2b7de3f8384cfac950beb3524 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sun, 25 Jun 2017 11:08:24 +0100 Subject: [PATCH 1/3] correct polarity of initial connections Fixes #2644 --- probe/endpoint/ebpf.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/probe/endpoint/ebpf.go b/probe/endpoint/ebpf.go index 1cce0c564..76ff85eb4 100644 --- a/probe/endpoint/ebpf.go +++ b/probe/endpoint/ebpf.go @@ -276,9 +276,9 @@ func (t *EbpfTracker) feedInitialConnections(conns procspy.ConnIter, seenTuples // We assume that tuple.fromPort < tuple.toPort is a connect event (outgoing) canonical, ok := seenTuples[tuple.key()] if (ok && canonical != tuple) || (!ok && tuple.fromPort < tuple.toPort) { - t.handleConnection(tracer.EventConnect, tuple, int(conn.Proc.PID), namespaceID) - } else { t.handleConnection(tracer.EventAccept, tuple, int(conn.Proc.PID), namespaceID) + } else { + t.handleConnection(tracer.EventConnect, tuple, int(conn.Proc.PID), namespaceID) } } for _, p := range processesWaitingInAccept { From bd6cdc44a8f3df9d7acd170c83cefd17060bdb42 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sun, 25 Jun 2017 11:22:32 +0100 Subject: [PATCH 2/3] refactor: extract some common code --- probe/endpoint/connection_tracker.go | 40 +++++++++++++++------------- probe/endpoint/ebpf.go | 20 ++------------ 2 files changed, 24 insertions(+), 36 deletions(-) diff --git a/probe/endpoint/connection_tracker.go b/probe/endpoint/connection_tracker.go index a4b8d3d85..dbe09304f 100644 --- a/probe/endpoint/connection_tracker.go +++ b/probe/endpoint/connection_tracker.go @@ -117,14 +117,8 @@ func (t *connectionTracker) performWalkProc(rpt *report.Report, hostNodeID strin return err } for conn := conns.Next(); conn != nil; conn = conns.Next() { + tuple, namespaceID, incoming := connectionTuple(conn, *seenTuples) var ( - namespaceID string - tuple = fourTuple{ - conn.LocalAddress.String(), - conn.RemoteAddress.String(), - conn.LocalPort, - conn.RemotePort, - } toNodeInfo = map[string]string{Procspied: "true"} fromNodeInfo = map[string]string{Procspied: "true"} ) @@ -132,17 +126,7 @@ func (t *connectionTracker) performWalkProc(rpt *report.Report, hostNodeID strin fromNodeInfo[process.PID] = strconv.FormatUint(uint64(conn.Proc.PID), 10) fromNodeInfo[report.HostNodeID] = hostNodeID } - - if conn.Proc.NetNamespaceID > 0 { - namespaceID = strconv.FormatUint(conn.Proc.NetNamespaceID, 10) - } - - // If we've already seen this connection, we should know the direction - // (or have already figured it out), so we normalize and use the - // canonical direction. Otherwise, we can use a port-heuristic to guess - // the direction. - canonical, ok := (*seenTuples)[tuple.key()] - if (ok && canonical != tuple) || (!ok && tuple.fromPort < tuple.toPort) { + if incoming { tuple.reverse() toNodeInfo, fromNodeInfo = fromNodeInfo, toNodeInfo } @@ -246,3 +230,23 @@ func (t *connectionTracker) Stop() error { t.reverseResolver.stop() return nil } + +func connectionTuple(conn *procspy.Connection, seenTuples map[string]fourTuple) (fourTuple, string, bool) { + namespaceID := "" + tuple := fourTuple{ + conn.LocalAddress.String(), + conn.RemoteAddress.String(), + conn.LocalPort, + conn.RemotePort, + } + if conn.Proc.NetNamespaceID > 0 { + namespaceID = strconv.FormatUint(conn.Proc.NetNamespaceID, 10) + } + + // If we've already seen this connection, we should know the direction + // (or have already figured it out), so we normalize and use the + // canonical direction. Otherwise, we can use a port-heuristic to guess + // the direction. + canonical, ok := seenTuples[tuple.key()] + return tuple, namespaceID, (ok && canonical != tuple) || (!ok && tuple.fromPort < tuple.toPort) +} diff --git a/probe/endpoint/ebpf.go b/probe/endpoint/ebpf.go index 76ff85eb4..ff23b4e21 100644 --- a/probe/endpoint/ebpf.go +++ b/probe/endpoint/ebpf.go @@ -258,24 +258,8 @@ func (t *EbpfTracker) walkConnections(f func(ebpfConnection)) { func (t *EbpfTracker) feedInitialConnections(conns procspy.ConnIter, seenTuples map[string]fourTuple, processesWaitingInAccept []int, hostNodeID string) { t.readyToHandleConnections = true for conn := conns.Next(); conn != nil; conn = conns.Next() { - var ( - namespaceID string - tuple = fourTuple{ - conn.LocalAddress.String(), - conn.RemoteAddress.String(), - conn.LocalPort, - conn.RemotePort, - } - ) - - if conn.Proc.NetNamespaceID > 0 { - namespaceID = strconv.FormatUint(conn.Proc.NetNamespaceID, 10) - } - - // We can use a port-heuristic to guess the direction. - // We assume that tuple.fromPort < tuple.toPort is a connect event (outgoing) - canonical, ok := seenTuples[tuple.key()] - if (ok && canonical != tuple) || (!ok && tuple.fromPort < tuple.toPort) { + tuple, namespaceID, incoming := connectionTuple(conn, seenTuples) + if incoming { t.handleConnection(tracer.EventAccept, tuple, int(conn.Proc.PID), namespaceID) } else { t.handleConnection(tracer.EventConnect, tuple, int(conn.Proc.PID), namespaceID) From b43003fd2b7817a274de98951e602162175d6a56 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sun, 25 Jun 2017 11:25:51 +0100 Subject: [PATCH 3/3] refactor: remove superfluous pointering --- probe/endpoint/connection_tracker.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/probe/endpoint/connection_tracker.go b/probe/endpoint/connection_tracker.go index dbe09304f..7d6f7ea2c 100644 --- a/probe/endpoint/connection_tracker.go +++ b/probe/endpoint/connection_tracker.go @@ -93,31 +93,31 @@ func (t *connectionTracker) ReportConnections(rpt *report.Report) { // seenTuples contains information about connections seen by conntrack and it will be passed to the /proc parser seenTuples := map[string]fourTuple{} - t.performFlowWalk(rpt, &seenTuples) + t.performFlowWalk(rpt, seenTuples) if t.conf.WalkProc && t.conf.Scanner != nil { - t.performWalkProc(rpt, hostNodeID, &seenTuples) + t.performWalkProc(rpt, hostNodeID, seenTuples) } } -func (t *connectionTracker) performFlowWalk(rpt *report.Report, seenTuples *map[string]fourTuple) { +func (t *connectionTracker) performFlowWalk(rpt *report.Report, seenTuples map[string]fourTuple) { // Consult the flowWalker for short-lived connections extraNodeInfo := map[string]string{ Conntracked: "true", } t.flowWalker.walkFlows(func(f flow, alive bool) { tuple := flowToTuple(f) - (*seenTuples)[tuple.key()] = tuple + seenTuples[tuple.key()] = tuple t.addConnection(rpt, tuple, "", extraNodeInfo, extraNodeInfo) }) } -func (t *connectionTracker) performWalkProc(rpt *report.Report, hostNodeID string, seenTuples *map[string]fourTuple) error { +func (t *connectionTracker) performWalkProc(rpt *report.Report, hostNodeID string, seenTuples map[string]fourTuple) error { conns, err := t.conf.Scanner.Connections() if err != nil { return err } for conn := conns.Next(); conn != nil; conn = conns.Next() { - tuple, namespaceID, incoming := connectionTuple(conn, *seenTuples) + tuple, namespaceID, incoming := connectionTuple(conn, seenTuples) var ( toNodeInfo = map[string]string{Procspied: "true"} fromNodeInfo = map[string]string{Procspied: "true"}