Beispiel #1
0
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
	}
}
Beispiel #2
0
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)
		}
	}
}
Beispiel #3
0
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)
	}
}
Beispiel #4
0
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)
	}
}
Beispiel #5
0
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)
	}
}
Beispiel #6
0
				},
				Client54002NodeID: report.NodeMetadata{
					"addr":            ClientIP,
					"port":            ClientPort54002,
					"pid":             ClientPID, // should be same as above!
					report.HostNodeID: ClientHostNodeID,
				},
				Server80NodeID: report.NodeMetadata{
					"addr":            ServerIP,
					"port":            ServerPort,
					"pid":             ServerPID,
					report.HostNodeID: ServerHostNodeID,
				},
			},
			EdgeMetadatas: report.EdgeMetadatas{
				report.MakeEdgeID(Client54001NodeID, Server80NodeID): report.EdgeMetadata{
					WithBytes:    true,
					BytesIngress: 100,
					BytesEgress:  10,
				},
				report.MakeEdgeID(Client54002NodeID, Server80NodeID): report.EdgeMetadata{
					WithBytes:    true,
					BytesIngress: 200,
					BytesEgress:  20,
				},

				report.MakeEdgeID(Server80NodeID, Client54001NodeID): report.EdgeMetadata{
					WithBytes:    true,
					BytesIngress: 10,
					BytesEgress:  100,
				},
Beispiel #7
0
// Render transforms a given Report into a set of RenderableNodes, which
// the UI will render collectively as a graph. Note that a RenderableNode will
// always be rendered with other nodes, and therefore contains limited detail.
//
// Nodes with the same mapped IDs will be merged.
func (m LeafMap) Render(rpt report.Report) RenderableNodes {
	var (
		t             = m.Selector(rpt)
		nodes         = RenderableNodes{}
		localNetworks = LocalNetworks(rpt)
	)

	// Build a set of RenderableNodes for all non-pseudo probes, and an
	// addressID to nodeID lookup map. Multiple addressIDs can map to the same
	// RenderableNodes.
	source2mapped := map[string]string{} // source node ID -> mapped node ID
	for nodeID, metadata := range t.NodeMetadatas {
		mapped, ok := m.Mapper(metadata)
		if !ok {
			continue
		}

		// mapped.ID needs not be unique over all addressIDs. If not, we merge with
		// the existing data, on the assumption that the MapFunc returns the same
		// data.
		existing, ok := nodes[mapped.ID]
		if ok {
			mapped.Merge(existing)
		}

		origins := mapped.Origins
		origins = origins.Add(nodeID)
		origins = origins.Add(metadata[report.HostNodeID])
		mapped.Origins = origins

		nodes[mapped.ID] = mapped
		source2mapped[nodeID] = mapped.ID
	}

	// Walk the graph and make connections.
	for src, dsts := range t.Adjacency {
		var (
			srcNodeID, ok     = report.ParseAdjacencyID(src)
			srcRenderableID   = source2mapped[srcNodeID] // must exist
			srcRenderableNode = nodes[srcRenderableID]   // must exist
		)
		if !ok {
			log.Printf("bad adjacency ID %q", src)
			continue
		}

		for _, dstNodeID := range dsts {
			dstRenderableID, ok := source2mapped[dstNodeID]
			if !ok {
				pseudoNode, ok := m.Pseudo(srcNodeID, srcRenderableNode, dstNodeID, localNetworks)
				if !ok {
					continue
				}
				dstRenderableID = pseudoNode.ID
				nodes[dstRenderableID] = pseudoNode
				source2mapped[dstNodeID] = dstRenderableID
			}

			srcRenderableNode.Adjacency = srcRenderableNode.Adjacency.Add(dstRenderableID)
			srcRenderableNode.Origins = srcRenderableNode.Origins.Add(srcNodeID)
			edgeID := report.MakeEdgeID(srcNodeID, dstNodeID)
			if md, ok := t.EdgeMetadatas[edgeID]; ok {
				srcRenderableNode.AggregateMetadata.Merge(AggregateMetadataOf(md))
			}
		}

		nodes[srcRenderableID] = srcRenderableNode
	}

	return nodes
}
Beispiel #8
0
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{
		Adjacency: report.Adjacency{
			report.MakeAdjacencyID(srcEndpointNodeID): report.MakeIDList(
				dstEndpointNodeID,
			),
		},
		EdgeMetadatas: report.EdgeMetadatas{
			report.MakeEdgeID(srcEndpointNodeID, dstEndpointNodeID): report.EdgeMetadata{
				EgressPacketCount: newu64(1),
				EgressByteCount:   newu64(256),
			},
		},
		NodeMetadatas: report.NodeMetadatas{
			srcEndpointNodeID: report.MakeNodeMetadata(),
		},
	}), 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{
		Adjacency: report.Adjacency{
			report.MakeAdjacencyID(srcAddressNodeID): report.MakeIDList(
				dstAddressNodeID,
			),
		},
		EdgeMetadatas: report.EdgeMetadatas{
			report.MakeEdgeID(srcAddressNodeID, dstAddressNodeID): report.EdgeMetadata{
				EgressPacketCount: newu64(1),
				EgressByteCount:   newu64(512),
			},
		},
		NodeMetadatas: report.NodeMetadatas{
			srcAddressNodeID: report.MakeNodeMetadata(),
		},
	}), rpt.Address; !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Beispiel #9
0
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
		}
	}
	hosts = append(hosts, []string{"1.2.3.4", "2.3.4.5"}...) // Some non-local ones, too.

	_, 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.MakeNodeMetadataWith(map[string]string{
				process.PID: "4000",
				"name":      c.srcProc,
				"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.MakeNodeMetadataWith(map[string]string{
				process.PID: "4000",
				"name":      c.dstProc,
				"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{
			MaxConnCountTCP: newu64(uint64(rand.Intn(100) + 10)),
		}
		r.Endpoint.EdgeMetadatas[edgeKeyIngress] = report.EdgeMetadata{
			MaxConnCountTCP: newu64(uint64(rand.Intn(100) + 10)),
		}

		// Address topology
		if _, ok := r.Address.NodeMetadatas[srcAddressID]; !ok {
			r.Address.NodeMetadatas[srcAddressID] = report.MakeNodeMetadataWith(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.MakeNodeMetadataWith(map[string]string{
				docker.Name: dst,
			})
		}
		r.Address.Adjacency[nodeDstAddressID] = r.Address.Adjacency[nodeDstAddressID].Add(srcAddressID)

		// Host data
		r.Host.NodeMetadatas["hostX"] = report.MakeNodeMetadataWith(map[string]string{
			"ts":             time.Now().UTC().Format(time.RFC3339Nano),
			"host_name":      "host-x",
			"local_networks": localNet.String(),
			"os":             "linux",
		})
	}

	return r
}
Beispiel #10
0
// Render transforms a given Report into a set of RenderableNodes, which
// the UI will render collectively as a graph. Note that a RenderableNode will
// always be rendered with other nodes, and therefore contains limited detail.
//
// Nodes with the same mapped IDs will be merged.
func (m LeafMap) Render(rpt report.Report) RenderableNodes {
	var (
		t             = m.Selector(rpt)
		nodes         = RenderableNodes{}
		localNetworks = LocalNetworks(rpt)
	)

	// Build a set of RenderableNodes for all non-pseudo probes, and an
	// addressID to nodeID lookup map. Multiple addressIDs can map to the same
	// RenderableNodes.
	source2mapped := map[string]report.IDList{} // source node ID -> mapped node IDs
	for nodeID, metadata := range t.NodeMetadatas {
		for _, mapped := range m.Mapper(metadata) {
			// mapped.ID needs not be unique over all addressIDs. If not, we merge with
			// the existing data, on the assumption that the MapFunc returns the same
			// data.
			existing, ok := nodes[mapped.ID]
			if ok {
				mapped.Merge(existing)
			}

			origins := mapped.Origins
			origins = origins.Add(nodeID)
			origins = origins.Add(metadata.Metadata[report.HostNodeID])
			mapped.Origins = origins

			nodes[mapped.ID] = mapped
			source2mapped[nodeID] = source2mapped[nodeID].Add(mapped.ID)
		}
	}

	mkPseudoNode := func(srcNodeID, dstNodeID string, srcIsClient bool) report.IDList {
		pseudoNode, ok := m.Pseudo(srcNodeID, dstNodeID, srcIsClient, localNetworks)
		if !ok {
			return report.MakeIDList()
		}
		pseudoNode.Origins = pseudoNode.Origins.Add(srcNodeID)
		existing, ok := nodes[pseudoNode.ID]
		if ok {
			pseudoNode.Merge(existing)
		}

		nodes[pseudoNode.ID] = pseudoNode
		source2mapped[pseudoNode.ID] = source2mapped[pseudoNode.ID].Add(srcNodeID)
		return report.MakeIDList(pseudoNode.ID)
	}

	// Walk the graph and make connections.
	for src, dsts := range t.Adjacency {
		srcNodeID, ok := report.ParseAdjacencyID(src)
		if !ok {
			log.Printf("bad adjacency ID %q", src)
			continue
		}

		srcRenderableIDs, ok := source2mapped[srcNodeID]
		if !ok {
			// One of the entries in dsts must be a non-pseudo node, unless
			// it was dropped by the mapping function.
			for _, dstNodeID := range dsts {
				if _, ok := source2mapped[dstNodeID]; ok {
					srcRenderableIDs = mkPseudoNode(srcNodeID, dstNodeID, true)
					break
				}
			}
		}
		if len(srcRenderableIDs) == 0 {
			continue
		}

		for _, srcRenderableID := range srcRenderableIDs {
			srcRenderableNode := nodes[srcRenderableID]

			for _, dstNodeID := range dsts {
				dstRenderableIDs, ok := source2mapped[dstNodeID]
				if !ok {
					dstRenderableIDs = mkPseudoNode(dstNodeID, srcNodeID, false)
				}
				if len(dstRenderableIDs) == 0 {
					continue
				}
				for _, dstRenderableID := range dstRenderableIDs {
					dstRenderableNode := nodes[dstRenderableID]
					srcRenderableNode.Adjacency = srcRenderableNode.Adjacency.Add(dstRenderableID)

					// We propagate edge metadata to nodes on both ends of the edges.
					// TODO we should 'reverse' one end of the edge meta data - ingress -> egress etc.
					if md, ok := t.EdgeMetadatas[report.MakeEdgeID(srcNodeID, dstNodeID)]; ok {
						srcRenderableNode.EdgeMetadata = srcRenderableNode.EdgeMetadata.Merge(md)
						dstRenderableNode.EdgeMetadata = dstRenderableNode.EdgeMetadata.Merge(md)
						nodes[dstRenderableID] = dstRenderableNode
					}
				}
			}

			nodes[srcRenderableID] = srcRenderableNode
		}
	}

	return nodes
}
Beispiel #11
0
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
		}
	}
}