func TestSpyWithProcesses(t *testing.T) { procspy.SetFixtures(fixConnectionsWithProcesses) const ( nodeID = "nikon" // TODO rename to hostID nodeName = "fishermans-friend" // TODO rename to hostNmae ) reporter := endpoint.NewReporter(nodeID, nodeName, false) r, _ := reporter.Report() // buf, _ := json.MarshalIndent(r, "", " ") ; t.Logf("\n%s\n", buf) var ( scopedLocal = report.MakeEndpointNodeID(nodeID, fixLocalAddress.String(), strconv.Itoa(int(fixLocalPort))) scopedRemote = report.MakeEndpointNodeID(nodeID, fixRemoteAddress.String(), strconv.Itoa(int(fixRemotePort))) localKey = report.MakeAdjacencyID(scopedLocal) ) if want, have := 1, len(r.Endpoint.Adjacency[localKey]); want != have { t.Fatalf("want %d, have %d", want, have) } if want, have := scopedRemote, r.Endpoint.Adjacency[localKey][0]; want != have { t.Fatalf("want %q, have %q", want, have) } for key, want := range map[string]string{ "pid": strconv.FormatUint(uint64(fixProcessPID), 10), } { if have := r.Endpoint.NodeMetadatas[scopedLocal].Metadata[key]; want != have { t.Errorf("Process.NodeMetadatas[%q][%q]: want %q, have %q", scopedLocal, key, want, have) } } }
func (r *Reporter) addConnection(rpt *report.Report, t fourTuple, extraFromNode, extraToNode map[string]string) { var ( fromEndpointNodeID = report.MakeEndpointNodeID(r.hostID, t.fromAddr, strconv.Itoa(int(t.fromPort))) toEndpointNodeID = report.MakeEndpointNodeID(r.hostID, t.toAddr, strconv.Itoa(int(t.toPort))) fromNode = report.MakeNodeWith(fromEndpointNodeID, map[string]string{ Addr: t.fromAddr, Port: strconv.Itoa(int(t.fromPort)), }).WithEdge(toEndpointNodeID, report.EdgeMetadata{}) toNode = report.MakeNodeWith(toEndpointNodeID, map[string]string{ Addr: t.toAddr, Port: strconv.Itoa(int(t.toPort)), }) ) // In case we have a reverse resolution for the IP, we can use it for // the name... if toNames, err := r.reverseResolver.get(t.toAddr); err == nil { toNode = toNode.WithSet(ReverseDNSNames, report.MakeStringSet(toNames...)) } if extraFromNode != nil { fromNode = fromNode.WithLatests(extraFromNode) } if extraToNode != nil { toNode = toNode.WithLatests(extraToNode) } rpt.Endpoint = rpt.Endpoint.AddNode(fromNode) rpt.Endpoint = rpt.Endpoint.AddNode(toNode) }
func TestMerge(t *testing.T) { var ( hostID = "xyz" src = newMockSource([]byte{}, nil) on = time.Millisecond off = time.Millisecond rpt = report.MakeReport() p = sniff.Packet{ SrcIP: "1.0.0.0", SrcPort: "1000", DstIP: "2.0.0.0", DstPort: "2000", Network: 512, Transport: 256, } _, ipnet, _ = net.ParseCIDR(p.SrcIP + "/24") // ;) localNets = report.Networks([]*net.IPNet{ipnet}) ) sniff.New(hostID, localNets, src, on, off).Merge(p, &rpt) var ( srcEndpointNodeID = report.MakeEndpointNodeID(hostID, p.SrcIP, p.SrcPort) dstEndpointNodeID = report.MakeEndpointNodeID(hostID, p.DstIP, p.DstPort) ) if want, have := (report.Topology{ Nodes: report.Nodes{ srcEndpointNodeID: report.MakeNode().WithEdge(dstEndpointNodeID, report.EdgeMetadata{ EgressPacketCount: newu64(1), EgressByteCount: newu64(256), }), dstEndpointNodeID: report.MakeNode(), }, }), rpt.Endpoint; !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } var ( srcAddressNodeID = report.MakeAddressNodeID(hostID, p.SrcIP) dstAddressNodeID = report.MakeAddressNodeID(hostID, p.DstIP) ) if want, have := (report.Topology{ Nodes: report.Nodes{ srcAddressNodeID: report.MakeNode().WithEdge(dstAddressNodeID, report.EdgeMetadata{ EgressPacketCount: newu64(1), EgressByteCount: newu64(512), }), dstAddressNodeID: report.MakeNode(), }, }), rpt.Address; !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
// applyNAT duplicates NodeMetadatas in the endpoint topology of a // report, based on the NAT table as returns by natTable. func (n *natmapper) applyNAT(rpt report.Report, scope string) { n.WalkFlows(func(f Flow) { mapping := toMapping(f) realEndpointID := report.MakeEndpointNodeID(scope, mapping.originalIP, strconv.Itoa(mapping.originalPort)) copyEndpointID := report.MakeEndpointNodeID(scope, mapping.rewrittenIP, strconv.Itoa(mapping.rewrittenPort)) nmd, ok := rpt.Endpoint.NodeMetadatas[realEndpointID] if !ok { return } rpt.Endpoint.NodeMetadatas[copyEndpointID] = nmd.Copy() }) }
func (rep *reporter) addConnection(r *report.Report, c *procspy.Connection) { var ( scopedLocal = report.MakeAddressNodeID(rep.hostID, c.LocalAddress.String()) scopedRemote = report.MakeAddressNodeID(rep.hostID, c.RemoteAddress.String()) key = report.MakeAdjacencyID(scopedLocal) edgeKey = report.MakeEdgeID(scopedLocal, scopedRemote) ) r.Address.Adjacency[key] = r.Address.Adjacency[key].Add(scopedRemote) if _, ok := r.Address.NodeMetadatas[scopedLocal]; !ok { r.Address.NodeMetadatas[scopedLocal] = report.NodeMetadata{ "name": rep.hostName, "addr": c.LocalAddress.String(), } } // Count the TCP connection. edgeMeta := r.Address.EdgeMetadatas[edgeKey] edgeMeta.WithConnCountTCP = true edgeMeta.MaxConnCountTCP++ r.Address.EdgeMetadatas[edgeKey] = edgeMeta if c.Proc.PID > 0 { var ( scopedLocal = report.MakeEndpointNodeID(rep.hostID, c.LocalAddress.String(), strconv.Itoa(int(c.LocalPort))) scopedRemote = report.MakeEndpointNodeID(rep.hostID, c.RemoteAddress.String(), strconv.Itoa(int(c.RemotePort))) key = report.MakeAdjacencyID(scopedLocal) edgeKey = report.MakeEdgeID(scopedLocal, scopedRemote) ) r.Endpoint.Adjacency[key] = r.Endpoint.Adjacency[key].Add(scopedRemote) if _, ok := r.Endpoint.NodeMetadatas[scopedLocal]; !ok { // First hit establishes NodeMetadata for scoped local address + port md := report.NodeMetadata{ "addr": c.LocalAddress.String(), "port": strconv.Itoa(int(c.LocalPort)), "pid": fmt.Sprintf("%d", c.Proc.PID), } r.Endpoint.NodeMetadatas[scopedLocal] = md } // Count the TCP connection. edgeMeta := r.Endpoint.EdgeMetadatas[edgeKey] edgeMeta.WithConnCountTCP = true edgeMeta.MaxConnCountTCP++ r.Endpoint.EdgeMetadatas[edgeKey] = edgeMeta } }
func TestEndpointNodeID(t *testing.T) { for _, bad := range []string{ clientAddressNodeID, serverAddressNodeID, unknownAddressNodeID, clientHostNodeID, serverHostNodeID, "host.com;1.2.3.4", "a;b", "a;", ";b", ";", "", } { if haveName, haveAddress, havePort, ok := report.ParseEndpointNodeID(bad); ok { t.Errorf("%q: expected failure, but got {%q, %q, %q}", bad, haveName, haveAddress, havePort) } } for input, want := range map[string]struct{ name, address, port string }{ report.MakeEndpointNodeID("host.com", "1.2.3.4", "c"): {"", "1.2.3.4", "c"}, "a;b;c": {"a", "b", "c"}, } { haveName, haveAddress, havePort, ok := report.ParseEndpointNodeID(input) if !ok { t.Errorf("%q: not OK", input) continue } if want.name != haveName || want.address != haveAddress || want.port != havePort { t.Errorf("%q: want %q, have {%q, %q, %q}", input, want, haveName, haveAddress, havePort) } } }
func TestEdgeID(t *testing.T) { for _, bad := range []string{ client54001EndpointNodeID, client54002EndpointNodeID, unknown1EndpointNodeID, unknown2EndpointNodeID, unknown3EndpointNodeID, clientAddressNodeID, serverAddressNodeID, unknownAddressNodeID, clientHostNodeID, serverHostNodeID, ">1.2.3.4", ">", ";", "", } { if srcNodeID, dstNodeID, ok := report.ParseEdgeID(bad); ok { t.Errorf("%q: expected failure, but got (%q, %q)", bad, srcNodeID, dstNodeID) } } for input, want := range map[string]struct{ srcNodeID, dstNodeID string }{ report.MakeEdgeID("a", report.MakeEndpointNodeID("a", "b", "c")): {"a", report.MakeEndpointNodeID("a", "b", "c")}, report.MakeEdgeID("a", report.MakeAddressNodeID("a", "b")): {"a", report.MakeAddressNodeID("a", "b")}, report.MakeEdgeID("a", report.MakeProcessNodeID("a", "b")): {"a", report.MakeProcessNodeID("a", "b")}, report.MakeEdgeID("a", report.MakeHostNodeID("a")): {"a", report.MakeHostNodeID("a")}, "host.com|1.2.3.4": {"host.com", "1.2.3.4"}, "a|b;c": {"a", "b;c"}, "a|b": {"a", "b"}, "a|": {"a", ""}, "|b": {"", "b"}, "|": {"", ""}, } { srcNodeID, dstNodeID, ok := report.ParseEdgeID(input) if !ok { t.Errorf("%q: not OK", input) continue } if want, have := want.srcNodeID, srcNodeID; want != have { t.Errorf("%q: want %q, have %q", input, want, have) } if want, have := want.dstNodeID, dstNodeID; want != have { t.Errorf("%q: want %q, have %q", input, want, have) } } }
func (r *Reporter) addConnection(rpt *report.Report, c *procspy.Connection) { var ( scopedLocal = report.MakeAddressNodeID(r.hostID, c.LocalAddress.String()) scopedRemote = report.MakeAddressNodeID(r.hostID, c.RemoteAddress.String()) key = report.MakeAdjacencyID(scopedLocal) edgeKey = report.MakeEdgeID(scopedLocal, scopedRemote) ) rpt.Address.Adjacency[key] = rpt.Address.Adjacency[key].Add(scopedRemote) if _, ok := rpt.Address.NodeMetadatas[scopedLocal]; !ok { rpt.Address.NodeMetadatas[scopedLocal] = report.NewNodeMetadata(map[string]string{ docker.Name: r.hostName, docker.Addr: c.LocalAddress.String(), }) } countTCPConnection(rpt.Address.EdgeMetadatas, edgeKey) if c.Proc.PID > 0 { var ( scopedLocal = report.MakeEndpointNodeID(r.hostID, c.LocalAddress.String(), strconv.Itoa(int(c.LocalPort))) scopedRemote = report.MakeEndpointNodeID(r.hostID, c.RemoteAddress.String(), strconv.Itoa(int(c.RemotePort))) key = report.MakeAdjacencyID(scopedLocal) edgeKey = report.MakeEdgeID(scopedLocal, scopedRemote) ) rpt.Endpoint.Adjacency[key] = rpt.Endpoint.Adjacency[key].Add(scopedRemote) if _, ok := rpt.Endpoint.NodeMetadatas[scopedLocal]; !ok { // First hit establishes NodeMetadata for scoped local address + port md := report.NewNodeMetadata(map[string]string{ "addr": c.LocalAddress.String(), "port": strconv.Itoa(int(c.LocalPort)), "pid": fmt.Sprintf("%d", c.Proc.PID), }) rpt.Endpoint.NodeMetadatas[scopedLocal] = md } countTCPConnection(rpt.Endpoint.EdgeMetadatas, edgeKey) } }
func (r *Reporter) addConnection(rpt *report.Report, c *procspy.Connection) { var ( localAddressNodeID = report.MakeAddressNodeID(r.hostID, c.LocalAddress.String()) remoteAddressNodeID = report.MakeAddressNodeID(r.hostID, c.RemoteAddress.String()) adjecencyID = report.MakeAdjacencyID(localAddressNodeID) edgeID = report.MakeEdgeID(localAddressNodeID, remoteAddressNodeID) ) rpt.Address.Adjacency[adjecencyID] = rpt.Address.Adjacency[adjecencyID].Add(remoteAddressNodeID) if _, ok := rpt.Address.NodeMetadatas[localAddressNodeID]; !ok { rpt.Address.NodeMetadatas[localAddressNodeID] = report.MakeNodeMetadataWith(map[string]string{ "name": r.hostName, Addr: c.LocalAddress.String(), }) } countTCPConnection(rpt.Address.EdgeMetadatas, edgeID) if c.Proc.PID > 0 { var ( localEndpointNodeID = report.MakeEndpointNodeID(r.hostID, c.LocalAddress.String(), strconv.Itoa(int(c.LocalPort))) remoteEndpointNodeID = report.MakeEndpointNodeID(r.hostID, c.RemoteAddress.String(), strconv.Itoa(int(c.RemotePort))) adjecencyID = report.MakeAdjacencyID(localEndpointNodeID) edgeID = report.MakeEdgeID(localEndpointNodeID, remoteEndpointNodeID) ) rpt.Endpoint.Adjacency[adjecencyID] = rpt.Endpoint.Adjacency[adjecencyID].Add(remoteEndpointNodeID) if _, ok := rpt.Endpoint.NodeMetadatas[localEndpointNodeID]; !ok { // First hit establishes NodeMetadata for scoped local address + port md := report.MakeNodeMetadataWith(map[string]string{ Addr: c.LocalAddress.String(), Port: strconv.Itoa(int(c.LocalPort)), process.PID: fmt.Sprint(c.Proc.PID), }) rpt.Endpoint.NodeMetadatas[localEndpointNodeID] = md } countTCPConnection(rpt.Endpoint.EdgeMetadatas, edgeID) } }
// applyNAT duplicates NodeMetadatas in the endpoint topology of a // report, based on the NAT table as returns by natTable. func applyNAT(rpt report.Report, scope string) error { mappings, err := natTable() if err != nil { return err } for _, mapping := range mappings { realEndpointID := report.MakeEndpointNodeID(scope, mapping.originalIP, strconv.Itoa(mapping.originalPort)) copyEndpointID := report.MakeEndpointNodeID(scope, mapping.rewrittenIP, strconv.Itoa(mapping.rewrittenPort)) nmd, ok := rpt.Endpoint.NodeMetadatas[realEndpointID] if !ok { continue } rpt.Endpoint.NodeMetadatas[copyEndpointID] = nmd.Copy() } return nil }
func TestInterpolateCounts(t *testing.T) { var ( hostID = "macbook-air" srcNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "5678") dstNodeID = report.MakeEndpointNodeID(hostID, "5.6.7.8", "9012") edgeID = report.MakeEdgeID(srcNodeID, dstNodeID) samplingCount = uint64(200) samplingTotal = uint64(2345) packetCount = uint64(123) byteCount = uint64(4096) ) r := report.MakeReport() r.Sampling.Count = samplingCount r.Sampling.Total = samplingTotal r.Endpoint.EdgeMetadatas[edgeID] = report.EdgeMetadata{ EgressPacketCount: newu64(packetCount), IngressPacketCount: newu64(packetCount), EgressByteCount: newu64(byteCount), IngressByteCount: newu64(byteCount), } interpolateCounts(r) var ( rate = float64(samplingCount) / float64(samplingTotal) factor = 1.0 / rate apply = func(v uint64) uint64 { return uint64(factor * float64(v)) } emd = r.Endpoint.EdgeMetadatas[edgeID] ) if want, have := apply(packetCount), (*emd.EgressPacketCount); want != have { t.Errorf("want %d packets, have %d", want, have) } if want, have := apply(packetCount), (*emd.IngressPacketCount); want != have { t.Errorf("want %d packets, have %d", want, have) } if want, have := apply(byteCount), (*emd.EgressByteCount); want != have { t.Errorf("want %d bytes, have %d", want, have) } if want, have := apply(byteCount), (*emd.IngressByteCount); want != have { t.Errorf("want %d bytes, have %d", want, have) } }
// ApplyNAT duplicates Nodes in the endpoint topology of a // report, based on the NAT table as returns by natTable. func (n NATMapper) ApplyNAT(rpt report.Report, scope string) { n.WalkFlows(func(f Flow) { var ( mapping = toMapping(f) realEndpointID = report.MakeEndpointNodeID(scope, mapping.originalIP, strconv.Itoa(mapping.originalPort)) copyEndpointPort = strconv.Itoa(mapping.rewrittenPort) copyEndpointID = report.MakeEndpointNodeID(scope, mapping.rewrittenIP, copyEndpointPort) node, ok = rpt.Endpoint.Nodes[realEndpointID] ) if !ok { return } node = node.Copy() node.Metadata[Addr] = mapping.rewrittenIP node.Metadata[Port] = copyEndpointPort node.Metadata["copy_of"] = realEndpointID rpt.Endpoint.AddNode(copyEndpointID, node) }) }
// applyNAT duplicates Nodes in the endpoint topology of a report, based on // the NAT table. func (n natMapper) applyNAT(rpt report.Report, scope string) { n.flowWalker.walkFlows(func(f flow) { var ( mapping = toMapping(f) realEndpointID = report.MakeEndpointNodeID(scope, mapping.originalIP, strconv.Itoa(mapping.originalPort)) copyEndpointPort = strconv.Itoa(mapping.rewrittenPort) copyEndpointID = report.MakeEndpointNodeID(scope, mapping.rewrittenIP, copyEndpointPort) node, ok = rpt.Endpoint.Nodes[realEndpointID] ) if !ok { return } rpt.Endpoint.AddNode(copyEndpointID, node.WithLatests(map[string]string{ Addr: mapping.rewrittenIP, Port: copyEndpointPort, "copy_of": realEndpointID, })) }) }
func TestEndpointIDAddresser(t *testing.T) { if nodeID := "1.2.4.5"; report.EndpointIDAddresser(nodeID) != nil { t.Errorf("%q: bad node ID parsed as good", nodeID) } var ( nodeID = report.MakeEndpointNodeID(clientHostID, clientAddress, "12345") want = net.ParseIP(clientAddress) have = report.EndpointIDAddresser(nodeID) ) if !reflect.DeepEqual(want, have) { t.Errorf("want %s, have %s", want, have) } }
func TestOriginHostTagger(t *testing.T) { var ( hostID = "foo" endpointNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "56789") // hostID ignored nodeMetadata = report.NodeMetadata{"foo": "bar"} ) r := report.MakeReport() r.Endpoint.NodeMetadatas[endpointNodeID] = nodeMetadata want := nodeMetadata.Merge(report.NodeMetadata{report.HostNodeID: report.MakeHostNodeID(hostID)}) rpt, _ := tag.NewOriginHostTagger(hostID).Tag(r) have := rpt.Endpoint.NodeMetadatas[endpointNodeID].Copy() if !reflect.DeepEqual(want, have) { t.Errorf("\nwant %+v\nhave %+v", want, have) } }
func TestTagger(t *testing.T) { var ( hostID = "foo" endpointNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "56789") // hostID ignored nodeMetadata = report.MakeNodeWith(map[string]string{"foo": "bar"}) ) r := report.MakeReport() r.Process.Nodes[endpointNodeID] = nodeMetadata want := nodeMetadata.Merge(report.MakeNodeWith(map[string]string{ report.HostNodeID: report.MakeHostNodeID(hostID), })) rpt, _ := host.NewTagger(hostID).Tag(r) have := rpt.Process.Nodes[endpointNodeID].Copy() if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestTagger(t *testing.T) { var ( hostID = "foo" probeID = "a1b2c3d4" endpointNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "56789") // hostID ignored node = report.MakeNodeWith(map[string]string{"foo": "bar"}) ) r := report.MakeReport() r.Process.AddNode(endpointNodeID, node) rpt, _ := host.NewTagger(hostID, probeID).Tag(r) have := rpt.Process.Nodes[endpointNodeID].Copy() // It should now have the host ID wantHostID := report.MakeHostNodeID(hostID) if hostID, ok := have.Latest.Lookup(report.HostNodeID); !ok || hostID != wantHostID { t.Errorf("Expected %q got %q", wantHostID, report.MakeHostNodeID(hostID)) } // It should now have the probe ID if haveProbeID, ok := have.Latest.Lookup(report.ProbeID); !ok || haveProbeID != probeID { t.Errorf("Expected %q got %q", probeID, haveProbeID) } // It should still have the other keys want := "bar" if have, ok := have.Latest.Lookup("foo"); !ok || have != want { t.Errorf("Expected %q got %q", want, have) } // It should have the host as a parent wantParent := report.MakeHostNodeID(hostID) if have, ok := have.Parents.Lookup(report.Host); !ok || len(have) != 1 || have[0] != wantParent { t.Errorf("Expected %q got %q", report.MakeStringSet(wantParent), have) } }
// DemoReport makes up a report. func DemoReport(nodeCount int) report.Report { r := report.MakeReport() // Make up some plausible IPv4 numbers hosts := []string{} ip := [4]int{192, 168, 1, 1} for range make([]struct{}, nodeCount) { hosts = append(hosts, fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])) ip[3]++ if ip[3] > 200 { ip[2]++ ip[3] = 1 } } // Some non-local ones. hosts = append(hosts, []string{"1.2.3.4", "2.3.4.5"}...) _, localNet, err := net.ParseCIDR("192.168.0.0/16") if err != nil { panic(err) } type conn struct { srcProc, dstProc string dstPort int } procPool := []conn{ {srcProc: "curl", dstPort: 80, dstProc: "apache"}, {srcProc: "wget", dstPort: 80, dstProc: "apache"}, {srcProc: "curl", dstPort: 80, dstProc: "nginx"}, {srcProc: "curl", dstPort: 8080, dstProc: "app1"}, {srcProc: "nginx", dstPort: 8080, dstProc: "app1"}, {srcProc: "nginx", dstPort: 8080, dstProc: "app2"}, {srcProc: "nginx", dstPort: 8080, dstProc: "app3"}, } connectionCount := nodeCount * 8 for i := 0; i < connectionCount; i++ { var ( c = procPool[rand.Intn(len(procPool))] src = hosts[rand.Intn(len(hosts))] dst = hosts[rand.Intn(len(hosts))] srcPort = rand.Intn(50000) + 10000 srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort)) dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort)) srcAddressID = report.MakeAddressNodeID("", src) dstAddressID = report.MakeAddressNodeID("", dst) ) // Endpoint topology r.Endpoint = r.Endpoint.WithNode(srcPortID, report.MakeNode().WithMetadata(map[string]string{ "pid": "4000", "name": c.srcProc, "domain": "node-" + src, }).WithEdge(dstPortID, report.EdgeMetadata{ MaxConnCountTCP: newu64(uint64(rand.Intn(100) + 10)), })) r.Endpoint = r.Endpoint.WithNode(dstPortID, report.MakeNode().WithMetadata(map[string]string{ "pid": "4000", "name": c.dstProc, "domain": "node-" + dst, }).WithEdge(srcPortID, report.EdgeMetadata{ MaxConnCountTCP: newu64(uint64(rand.Intn(100) + 10)), })) // Address topology r.Address = r.Address.WithNode(srcAddressID, report.MakeNode().WithMetadata(map[string]string{ "name": src, }).WithAdjacent(dstAddressID)) r.Address = r.Address.WithNode(dstAddressID, report.MakeNode().WithMetadata(map[string]string{ "name": dst, }).WithAdjacent(srcAddressID)) // Host data r.Host = r.Host.WithNode("hostX", report.MakeNodeWith(map[string]string{ "ts": time.Now().UTC().Format(time.RFC3339Nano), "host_name": "host-x", "local_networks": localNet.String(), "os": "linux", })) } return r }
"github.com/weaveworks/scope/report" ) var ( clientHostID = "client.host.com" clientHostName = clientHostID clientHostNodeID = report.MakeHostNodeID(clientHostID) clientAddress = "10.10.10.20" serverHostID = "server.host.com" serverHostName = serverHostID serverHostNodeID = report.MakeHostNodeID(serverHostID) serverAddress = "10.10.10.1" unknownHostID = "" // by definition, we don't know it unknownAddress = "172.16.93.112" // will be a pseudonode, no corresponding host client54001EndpointNodeID = report.MakeEndpointNodeID(clientHostID, clientAddress, "54001") // i.e. curl client54002EndpointNodeID = report.MakeEndpointNodeID(clientHostID, clientAddress, "54002") // also curl server80EndpointNodeID = report.MakeEndpointNodeID(serverHostID, serverAddress, "80") // i.e. apache unknown1EndpointNodeID = report.MakeEndpointNodeID(unknownHostID, unknownAddress, "10001") unknown2EndpointNodeID = report.MakeEndpointNodeID(unknownHostID, unknownAddress, "10002") unknown3EndpointNodeID = report.MakeEndpointNodeID(unknownHostID, unknownAddress, "10003") clientAddressNodeID = report.MakeAddressNodeID(clientHostID, clientAddress) serverAddressNodeID = report.MakeAddressNodeID(serverHostID, serverAddress) unknownAddressNodeID = report.MakeAddressNodeID(unknownHostID, unknownAddress) ) func TestAdjacencyID(t *testing.T) { for _, bad := range []string{ client54001EndpointNodeID, client54002EndpointNodeID,
// DemoReport makes up a report. func DemoReport(nodeCount int) report.Report { r := report.MakeReport() // Make up some plausible IPv4 numbers hosts := []string{} ip := [4]int{192, 168, 1, 1} for range make([]struct{}, nodeCount) { hosts = append(hosts, fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])) ip[3]++ if ip[3] > 200 { ip[2]++ ip[3] = 1 } } // Some non-local ones. hosts = append(hosts, []string{"1.2.3.4", "2.3.4.5"}...) _, localNet, err := net.ParseCIDR("192.168.0.0/16") if err != nil { panic(err) } type conn struct { srcProc, dstProc string dstPort int } procPool := []conn{ {srcProc: "curl", dstPort: 80, dstProc: "apache"}, {srcProc: "wget", dstPort: 80, dstProc: "apache"}, {srcProc: "curl", dstPort: 80, dstProc: "nginx"}, {srcProc: "curl", dstPort: 8080, dstProc: "app1"}, {srcProc: "nginx", dstPort: 8080, dstProc: "app1"}, {srcProc: "nginx", dstPort: 8080, dstProc: "app2"}, {srcProc: "nginx", dstPort: 8080, dstProc: "app3"}, } connectionCount := nodeCount * 2 for i := 0; i < connectionCount; i++ { var ( c = procPool[rand.Intn(len(procPool))] src = hosts[rand.Intn(len(hosts))] dst = hosts[rand.Intn(len(hosts))] srcPort = rand.Intn(50000) + 10000 srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort)) dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort)) srcID = report.MakeAdjacencyID(srcPortID) dstID = report.MakeAdjacencyID(dstPortID) srcAddressID = report.MakeAddressNodeID("", src) dstAddressID = report.MakeAddressNodeID("", dst) nodeSrcAddressID = report.MakeAdjacencyID(srcAddressID) nodeDstAddressID = report.MakeAdjacencyID(dstAddressID) ) // Endpoint topology if _, ok := r.Endpoint.NodeMetadatas[srcPortID]; !ok { r.Endpoint.NodeMetadatas[srcPortID] = report.NewNodeMetadata(map[string]string{ docker.PID: "4000", docker.Name: c.srcProc, docker.Domain: "node-" + src, }) } r.Endpoint.Adjacency[srcID] = r.Endpoint.Adjacency[srcID].Add(dstPortID) if _, ok := r.Endpoint.NodeMetadatas[dstPortID]; !ok { r.Endpoint.NodeMetadatas[dstPortID] = report.NewNodeMetadata(map[string]string{ docker.PID: "4000", docker.Name: c.dstProc, docker.Domain: "node-" + dst, }) } r.Endpoint.Adjacency[dstID] = r.Endpoint.Adjacency[dstID].Add(srcPortID) var ( edgeKeyEgress = report.MakeEdgeID(srcPortID, dstPortID) edgeKeyIngress = report.MakeEdgeID(dstPortID, srcPortID) ) r.Endpoint.EdgeMetadatas[edgeKeyEgress] = report.EdgeMetadata{ WithConnCountTCP: true, MaxConnCountTCP: uint(rand.Intn(100) + 10), } r.Endpoint.EdgeMetadatas[edgeKeyIngress] = report.EdgeMetadata{ WithConnCountTCP: true, MaxConnCountTCP: uint(rand.Intn(100) + 10), } // Address topology if _, ok := r.Address.NodeMetadatas[srcAddressID]; !ok { r.Address.NodeMetadatas[srcAddressID] = report.NewNodeMetadata(map[string]string{ docker.Name: src, }) } r.Address.Adjacency[nodeSrcAddressID] = r.Address.Adjacency[nodeSrcAddressID].Add(dstAddressID) if _, ok := r.Address.NodeMetadatas[dstAddressID]; !ok { r.Address.NodeMetadatas[dstAddressID] = report.NewNodeMetadata(map[string]string{ docker.Name: dst, }) } r.Address.Adjacency[nodeDstAddressID] = r.Address.Adjacency[nodeDstAddressID].Add(srcAddressID) // Host data r.Host.NodeMetadatas["hostX"] = report.NewNodeMetadata(map[string]string{ "ts": time.Now().UTC().Format(time.RFC3339Nano), "host_name": "host-x", "local_networks": localNet.String(), "os": "linux", }) } return r }
func TestNat(t *testing.T) { // test that two containers, on the docker network, get their connections mapped // correctly. // the setup is this: // // container2 (10.0.47.2:222222), host2 (2.3.4.5:22223) -> // host1 (1.2.3.4:80), container1 (10.0.47.2:80) // from the PoV of host1 { flow := makeFlow("") addIndependant(&flow, 1, "") flow.Original = addMeta(&flow, "original", "2.3.4.5", "1.2.3.4", 222222, 80) flow.Reply = addMeta(&flow, "reply", "10.0.47.1", "2.3.4.5", 80, 222222) ct := &mockConntracker{ flows: []endpoint.Flow{flow}, } have := report.MakeReport() originalID := report.MakeEndpointNodeID("host1", "10.0.47.1", "80") have.Endpoint.AddNode(originalID, report.MakeNodeWith(report.Metadata{ endpoint.Addr: "10.0.47.1", endpoint.Port: "80", "foo": "bar", })) want := have.Copy() want.Endpoint.AddNode(report.MakeEndpointNodeID("host1", "1.2.3.4", "80"), report.MakeNodeWith(report.Metadata{ endpoint.Addr: "1.2.3.4", endpoint.Port: "80", "copy_of": originalID, "foo": "bar", })) natmapper := endpoint.NewNATMapper(ct) natmapper.ApplyNAT(have, "host1") if !reflect.DeepEqual(want, have) { t.Fatal(test.Diff(want, have)) } } // form the PoV of host2 { flow := makeFlow("") addIndependant(&flow, 2, "") flow.Original = addMeta(&flow, "original", "10.0.47.2", "1.2.3.4", 22222, 80) flow.Reply = addMeta(&flow, "reply", "1.2.3.4", "2.3.4.5", 80, 22223) ct := &mockConntracker{ flows: []endpoint.Flow{flow}, } have := report.MakeReport() originalID := report.MakeEndpointNodeID("host2", "10.0.47.2", "22222") have.Endpoint.AddNode(originalID, report.MakeNodeWith(report.Metadata{ endpoint.Addr: "10.0.47.2", endpoint.Port: "22222", "foo": "baz", })) want := have.Copy() want.Endpoint.AddNode(report.MakeEndpointNodeID("host2", "2.3.4.5", "22223"), report.MakeNodeWith(report.Metadata{ endpoint.Addr: "2.3.4.5", endpoint.Port: "22223", "copy_of": originalID, "foo": "baz", })) natmapper := endpoint.NewNATMapper(ct) natmapper.ApplyNAT(have, "host1") if !reflect.DeepEqual(want, have) { t.Fatal(test.Diff(want, have)) } } }
"github.com/weaveworks/scope/common/mtime" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/endpoint" "github.com/weaveworks/scope/probe/host" "github.com/weaveworks/scope/render" "github.com/weaveworks/scope/report" ) var ( serverHostID = "host1" serverHostNodeID = report.MakeHostNodeID(serverHostID) randomIP = "3.4.5.6" randomPort = "56789" randomEndpointNodeID = report.MakeEndpointNodeID(serverHostID, randomIP, randomPort) serverIP = "192.168.1.1" serverPort = "80" serverEndpointNodeID = report.MakeEndpointNodeID(serverHostID, serverIP, serverPort) container1ID = "11b2c3d4e5" container1IP = "192.168.0.1" container1Name = "foo" container1NodeID = report.MakeContainerNodeID(container1ID) container1Port = "16782" container1EndpointNodeID = report.MakeEndpointNodeID(serverHostID, container1IP, container1Port) duplicatedIP = "192.168.0.2" duplicatedPort = "80"
func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr string, localPort, remotePort uint16, proc *procspy.Proc) { localIsClient := int(localPort) > int(remotePort) // Update address topology { var ( localAddressNodeID = report.MakeAddressNodeID(r.hostID, localAddr) remoteAddressNodeID = report.MakeAddressNodeID(r.hostID, remoteAddr) adjacencyID = "" edgeID = "" ) if localIsClient { adjacencyID = report.MakeAdjacencyID(localAddressNodeID) rpt.Address.Adjacency[adjacencyID] = rpt.Address.Adjacency[adjacencyID].Add(remoteAddressNodeID) edgeID = report.MakeEdgeID(localAddressNodeID, remoteAddressNodeID) } else { adjacencyID = report.MakeAdjacencyID(remoteAddressNodeID) rpt.Address.Adjacency[adjacencyID] = rpt.Address.Adjacency[adjacencyID].Add(localAddressNodeID) edgeID = report.MakeEdgeID(remoteAddressNodeID, localAddressNodeID) } countTCPConnection(rpt.Address.EdgeMetadatas, edgeID) if _, ok := rpt.Address.NodeMetadatas[localAddressNodeID]; !ok { rpt.Address.NodeMetadatas[localAddressNodeID] = report.MakeNodeMetadataWith(map[string]string{ "name": r.hostName, Addr: localAddr, }) } } // Update endpoint topology if r.includeProcesses { var ( localEndpointNodeID = report.MakeEndpointNodeID(r.hostID, localAddr, strconv.Itoa(int(localPort))) remoteEndpointNodeID = report.MakeEndpointNodeID(r.hostID, remoteAddr, strconv.Itoa(int(remotePort))) adjacencyID = "" edgeID = "" ) if localIsClient { adjacencyID = report.MakeAdjacencyID(localEndpointNodeID) rpt.Endpoint.Adjacency[adjacencyID] = rpt.Endpoint.Adjacency[adjacencyID].Add(remoteEndpointNodeID) edgeID = report.MakeEdgeID(localEndpointNodeID, remoteEndpointNodeID) } else { adjacencyID = report.MakeAdjacencyID(remoteEndpointNodeID) rpt.Endpoint.Adjacency[adjacencyID] = rpt.Endpoint.Adjacency[adjacencyID].Add(localEndpointNodeID) edgeID = report.MakeEdgeID(remoteEndpointNodeID, localEndpointNodeID) } countTCPConnection(rpt.Endpoint.EdgeMetadatas, edgeID) md, ok := rpt.Endpoint.NodeMetadatas[localEndpointNodeID] updated := !ok if !ok { md = report.MakeNodeMetadataWith(map[string]string{ Addr: localAddr, Port: strconv.Itoa(int(localPort)), }) } if proc != nil && proc.PID > 0 { pid := strconv.FormatUint(uint64(proc.PID), 10) updated = updated || md.Metadata[process.PID] != pid md.Metadata[process.PID] = pid } if updated { rpt.Endpoint.NodeMetadatas[localEndpointNodeID] = md } } }
ServerIP = "192.168.1.1" ClientPort54001 = "54001" ClientPort54002 = "54002" ServerPort = "80" ClientHostName = ClientHostID ServerHostName = ServerHostID ClientPID = "10001" ServerPID = "215" NonContainerPID = "1234" ClientHostNodeID = report.MakeHostNodeID(ClientHostID) ServerHostNodeID = report.MakeHostNodeID(ServerHostID) Client54001NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54001) // curl (1) Client54002NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54002) // curl (2) Server80NodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort) // apache UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, "10.10.10.10", "54010") // we want to ensure two unknown clients, connnected UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, "10.10.10.10", "54020") // to the same server, are deduped. UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, "10.10.10.11", "54020") // Check this one isn't deduped RandomClientNodeID = report.MakeEndpointNodeID(ServerHostID, "51.52.53.54", "12345") // this should become an internet node ClientProcessNodeID = report.MakeProcessNodeID(ClientHostID, ClientPID) ServerProcessNodeID = report.MakeProcessNodeID(ServerHostID, ServerPID) NonContainerProcessNodeID = report.MakeProcessNodeID(ServerHostID, NonContainerPID) ClientContainerID = "a1b2c3d4e5" ServerContainerID = "5e4d3c2b1a" ClientContainerNodeID = report.MakeContainerNodeID(ClientHostID, ClientContainerID) ServerContainerNodeID = report.MakeContainerNodeID(ServerHostID, ServerContainerID)
"github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/endpoint" "github.com/weaveworks/scope/probe/host" "github.com/weaveworks/scope/render" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test" ) var ( serverHostID = "host1" serverHostNodeID = report.MakeHostNodeID(serverHostID) randomIP = "3.4.5.6" randomPort = "56789" randomEndpointNodeID = report.MakeEndpointNodeID(serverHostID, randomIP, randomPort) serverIP = "192.168.1.1" serverPort = "80" serverEndpointNodeID = report.MakeEndpointNodeID(serverHostID, serverIP, serverPort) containerID = "a1b2c3d4e5" containerIP = "192.168.0.1" containerName = "foo" containerNodeID = report.MakeContainerNodeID(containerID) rpt = report.Report{ Endpoint: report.Topology{ Nodes: report.Nodes{ randomEndpointNodeID: report.MakeNode().WithLatests(map[string]string{ endpoint.Addr: randomIP,
// Merge puts the packet into the report. // // Note that, for the moment, we encode bidirectional traffic as ingress and // egress traffic on a single edge whose src is local and dst is remote. That // is, if we see a packet from the remote addr 9.8.7.6 to the local addr // 1.2.3.4, we apply it as *ingress* on the edge (1.2.3.4 -> 9.8.7.6). func (s *Sniffer) Merge(p Packet, rpt *report.Report) { if p.SrcIP == "" || p.DstIP == "" { return } // One end of the traffic has to be local. Otherwise, we don't know how to // construct the edge. // // If we need to get around this limitation, we may be able to change the // semantics of the report, and allow the src side of edges to be from // anywhere. But that will have ramifications throughout Scope (read: it // may violate implicit invariants) and needs to be thought through. var ( srcLocal = s.localNets.Contains(net.ParseIP(p.SrcIP)) dstLocal = s.localNets.Contains(net.ParseIP(p.DstIP)) localIP string remoteIP string localPort string remotePort string egress bool ) switch { case srcLocal && !dstLocal: localIP, localPort, remoteIP, remotePort, egress = p.SrcIP, p.SrcPort, p.DstIP, p.DstPort, true case !srcLocal && dstLocal: localIP, localPort, remoteIP, remotePort, egress = p.DstIP, p.DstPort, p.SrcIP, p.SrcPort, false case srcLocal && dstLocal: localIP, localPort, remoteIP, remotePort, egress = p.SrcIP, p.SrcPort, p.DstIP, p.DstPort, true // loopback case !srcLocal && !dstLocal: log.Printf("sniffer ignoring remote-to-remote (%s -> %s) traffic", p.SrcIP, p.DstIP) return } addAdjacency := func(t report.Topology, srcNodeID, dstNodeID string) report.Topology { result := t.WithNode(srcNodeID, report.MakeNode().WithAdjacent(dstNodeID)) result = result.WithNode(dstNodeID, report.MakeNode()) return result } // For sure, we can add to the address topology. { var ( srcNodeID = report.MakeAddressNodeID(s.hostID, localIP) dstNodeID = report.MakeAddressNodeID(s.hostID, remoteIP) ) rpt.Address = addAdjacency(rpt.Address, srcNodeID, dstNodeID) emd := rpt.Address.Nodes[srcNodeID].Edges[dstNodeID] if egress { if emd.EgressPacketCount == nil { emd.EgressPacketCount = new(uint64) } *emd.EgressPacketCount++ if emd.EgressByteCount == nil { emd.EgressByteCount = new(uint64) } *emd.EgressByteCount += uint64(p.Network) } else { if emd.IngressPacketCount == nil { emd.IngressPacketCount = new(uint64) } *emd.IngressPacketCount++ if emd.IngressByteCount == nil { emd.IngressByteCount = new(uint64) } *emd.IngressByteCount += uint64(p.Network) } rpt.Address.Nodes[srcNodeID].Edges[dstNodeID] = emd } // If we have ports, we can add to the endpoint topology, too. if p.SrcPort != "" && p.DstPort != "" { var ( srcNodeID = report.MakeEndpointNodeID(s.hostID, localIP, localPort) dstNodeID = report.MakeEndpointNodeID(s.hostID, remoteIP, remotePort) ) rpt.Endpoint = addAdjacency(rpt.Endpoint, srcNodeID, dstNodeID) emd := rpt.Endpoint.Nodes[srcNodeID].Edges[dstNodeID] if egress { if emd.EgressPacketCount == nil { emd.EgressPacketCount = new(uint64) } *emd.EgressPacketCount++ if emd.EgressByteCount == nil { emd.EgressByteCount = new(uint64) } *emd.EgressByteCount += uint64(p.Transport) } else { if emd.IngressPacketCount == nil { emd.IngressPacketCount = new(uint64) } *emd.IngressPacketCount++ if emd.IngressByteCount == nil { emd.IngressByteCount = new(uint64) } *emd.IngressByteCount += uint64(p.Transport) } rpt.Endpoint.Nodes[srcNodeID].Edges[dstNodeID] = emd } }
func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr string, localPort, remotePort uint16, extraLocalNode, extraRemoteNode *report.Node) { localIsClient := int(localPort) > int(remotePort) // Update address topology { var ( localAddressNodeID = report.MakeAddressNodeID(r.hostID, localAddr) remoteAddressNodeID = report.MakeAddressNodeID(r.hostID, remoteAddr) localNode = report.MakeNodeWith(map[string]string{ "name": r.hostName, Addr: localAddr, }) remoteNode = report.MakeNodeWith(map[string]string{ Addr: remoteAddr, }) ) // In case we have a reverse resolution for the IP, we can use it for // the name... if revRemoteName, err := r.revResolver.Get(remoteAddr); err == nil { remoteNode = remoteNode.WithMetadata(map[string]string{ "name": revRemoteName, }) } if localIsClient { // New nodes are merged into the report so we don't need to do any // counting here; the merge does it for us. localNode = localNode.WithEdge(remoteAddressNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } else { remoteNode = localNode.WithEdge(localAddressNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } if extraLocalNode != nil { localNode = localNode.Merge(*extraLocalNode) } if extraRemoteNode != nil { remoteNode = remoteNode.Merge(*extraRemoteNode) } rpt.Address = rpt.Address.AddNode(localAddressNodeID, localNode) rpt.Address = rpt.Address.AddNode(remoteAddressNodeID, remoteNode) } // Update endpoint topology if r.includeProcesses { var ( localEndpointNodeID = report.MakeEndpointNodeID(r.hostID, localAddr, strconv.Itoa(int(localPort))) remoteEndpointNodeID = report.MakeEndpointNodeID(r.hostID, remoteAddr, strconv.Itoa(int(remotePort))) localNode = report.MakeNodeWith(map[string]string{ Addr: localAddr, Port: strconv.Itoa(int(localPort)), }) remoteNode = report.MakeNodeWith(map[string]string{ Addr: remoteAddr, Port: strconv.Itoa(int(remotePort)), }) ) // In case we have a reverse resolution for the IP, we can use it for // the name... if revRemoteName, err := r.revResolver.Get(remoteAddr); err == nil { remoteNode = remoteNode.WithMetadata(map[string]string{ "name": revRemoteName, }) } if localIsClient { // New nodes are merged into the report so we don't need to do any // counting here; the merge does it for us. localNode = localNode.WithEdge(remoteEndpointNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } else { remoteNode = remoteNode.WithEdge(localEndpointNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } if extraLocalNode != nil { localNode = localNode.Merge(*extraLocalNode) } if extraRemoteNode != nil { remoteNode = remoteNode.Merge(*extraRemoteNode) } rpt.Endpoint = rpt.Endpoint.AddNode(localEndpointNodeID, localNode) rpt.Endpoint = rpt.Endpoint.AddNode(remoteEndpointNodeID, remoteNode) } }
func TestNat(t *testing.T) { mtime.NowForce(mtime.Now()) defer mtime.NowReset() // test that two containers, on the docker network, get their connections mapped // correctly. // the setup is this: // // container2 (10.0.47.2:222222), host2 (2.3.4.5:22223) -> // host1 (1.2.3.4:80), container1 (10.0.47.2:80) // from the PoV of host1 { f := makeFlow("") addIndependant(&f, 1, "") f.Original = addMeta(&f, "original", "2.3.4.5", "1.2.3.4", 222222, 80) f.Reply = addMeta(&f, "reply", "10.0.47.1", "2.3.4.5", 80, 222222) ct := &mockFlowWalker{ flows: []flow{f}, } have := report.MakeReport() originalID := report.MakeEndpointNodeID("host1", "10.0.47.1", "80") have.Endpoint.AddNode(originalID, report.MakeNodeWith(map[string]string{ Addr: "10.0.47.1", Port: "80", "foo": "bar", })) want := have.Copy() want.Endpoint.AddNode(report.MakeEndpointNodeID("host1", "1.2.3.4", "80"), report.MakeNodeWith(map[string]string{ Addr: "1.2.3.4", Port: "80", "copy_of": originalID, "foo": "bar", })) makeNATMapper(ct).applyNAT(have, "host1") if !reflect.DeepEqual(want, have) { t.Fatal(test.Diff(want, have)) } } // form the PoV of host2 { f := makeFlow("") addIndependant(&f, 2, "") f.Original = addMeta(&f, "original", "10.0.47.2", "1.2.3.4", 22222, 80) f.Reply = addMeta(&f, "reply", "1.2.3.4", "2.3.4.5", 80, 22223) ct := &mockFlowWalker{ flows: []flow{f}, } have := report.MakeReport() originalID := report.MakeEndpointNodeID("host2", "10.0.47.2", "22222") have.Endpoint.AddNode(originalID, report.MakeNodeWith(map[string]string{ Addr: "10.0.47.2", Port: "22222", "foo": "baz", })) want := have.Copy() want.Endpoint.AddNode(report.MakeEndpointNodeID("host2", "2.3.4.5", "22223"), report.MakeNodeWith(map[string]string{ Addr: "2.3.4.5", Port: "22223", "copy_of": originalID, "foo": "baz", })) makeNATMapper(ct).applyNAT(have, "host1") if !reflect.DeepEqual(want, have) { t.Fatal(test.Diff(want, have)) } } }
ServerHostName = ServerHostID Client1PID = "10001" Client2PID = "30020" ServerPID = "215" NonContainerPID = "1234" Client1Comm = "curl" Client2Comm = "curl" ServerComm = "apache" NonContainerComm = "bash" ClientHostNodeID = report.MakeHostNodeID(ClientHostID) ServerHostNodeID = report.MakeHostNodeID(ServerHostID) Client54001NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54001) // curl (1) Client54002NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54002) // curl (2) Server80NodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort) // apache UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient1IP, UnknownClient1Port) // we want to ensure two unknown clients, connnected UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient2IP, UnknownClient2Port) // to the same server, are deduped. UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient3IP, UnknownClient3Port) // Check this one isn't deduped RandomClientNodeID = report.MakeEndpointNodeID(ServerHostID, RandomClientIP, RandomClientPort) // this should become an internet node NonContainerNodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, NonContainerClientPort) GoogleEndpointNodeID = report.MakeEndpointNodeID(ServerHostID, GoogleIP, GooglePort) ClientProcess1NodeID = report.MakeProcessNodeID(ClientHostID, Client1PID) ClientProcess2NodeID = report.MakeProcessNodeID(ClientHostID, Client2PID) ServerProcessNodeID = report.MakeProcessNodeID(ServerHostID, ServerPID) NonContainerProcessNodeID = report.MakeProcessNodeID(ServerHostID, NonContainerPID) ClientContainerID = "a1b2c3d4e5"
func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr string, localPort, remotePort uint16, proc *procspy.Proc) { var ( localIsClient = int(localPort) > int(remotePort) hostNodeID = report.MakeHostNodeID(r.hostID) ) // Update address topology { var ( localAddressNodeID = report.MakeAddressNodeID(r.hostID, localAddr) remoteAddressNodeID = report.MakeAddressNodeID(r.hostID, remoteAddr) localNode = report.MakeNodeWith(map[string]string{ "name": r.hostName, Addr: localAddr, report.HostNodeID: hostNodeID, }) remoteNode = report.MakeNodeWith(map[string]string{ Addr: remoteAddr, }) ) if localIsClient { // New nodes are merged into the report so we don't need to do any counting here; the merge does it for us. localNode = localNode.WithEdge(remoteAddressNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } else { remoteNode = localNode.WithEdge(localAddressNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } rpt.Address = rpt.Address.WithNode(localAddressNodeID, localNode) rpt.Address = rpt.Address.WithNode(remoteAddressNodeID, remoteNode) } // Update endpoint topology if r.includeProcesses { var ( localEndpointNodeID = report.MakeEndpointNodeID(r.hostID, localAddr, strconv.Itoa(int(localPort))) remoteEndpointNodeID = report.MakeEndpointNodeID(r.hostID, remoteAddr, strconv.Itoa(int(remotePort))) localNode = report.MakeNodeWith(map[string]string{ Addr: localAddr, Port: strconv.Itoa(int(localPort)), report.HostNodeID: hostNodeID, }) remoteNode = report.MakeNodeWith(map[string]string{ Addr: remoteAddr, Port: strconv.Itoa(int(remotePort)), }) ) if localIsClient { // New nodes are merged into the report so we don't need to do any counting here; the merge does it for us. localNode = localNode.WithEdge(remoteEndpointNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } else { remoteNode = remoteNode.WithEdge(localEndpointNodeID, report.EdgeMetadata{ MaxConnCountTCP: newu64(1), }) } if proc != nil && proc.PID > 0 { localNode.Metadata[process.PID] = strconv.FormatUint(uint64(proc.PID), 10) } rpt.Endpoint = rpt.Endpoint.WithNode(localEndpointNodeID, localNode) rpt.Endpoint = rpt.Endpoint.WithNode(remoteEndpointNodeID, remoteNode) } }