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 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) } }
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) } }
}, 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, },
// 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 }
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)) } }
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 }
// 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 }
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 } } }