From 0361b11b87f066c641d3bbe2448571bfe64f13cc Mon Sep 17 00:00:00 2001 From: Peter Bourgon Date: Mon, 3 Aug 2015 12:25:56 +0200 Subject: [PATCH] Fix bugs in how we report bandwidth --- probe/sniff/sniffer.go | 44 ++++++++++++++++++++++++------------------ render/render.go | 1 + report/topology.go | 4 ++-- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/probe/sniff/sniffer.go b/probe/sniff/sniffer.go index 91dff56c5..e7d2c00bf 100644 --- a/probe/sniff/sniffer.go +++ b/probe/sniff/sniffer.go @@ -145,7 +145,6 @@ type Packet struct { func (s *Sniffer) read(src gopacket.ZeroCopyPacketDataSource, dst chan Packet, process, total, count *uint64) { var ( - p Packet data []byte err error ) @@ -167,6 +166,7 @@ func (s *Sniffer) read(src gopacket.ZeroCopyPacketDataSource, dst chan Packet, p // We'll always get an error when we encounter a layer type for // which we haven't configured a decoder. } + var p Packet for _, t := range s.decoded { switch t { case layers.LayerTypeEthernet: @@ -178,16 +178,16 @@ func (s *Sniffer) read(src gopacket.ZeroCopyPacketDataSource, dst chan Packet, p case layers.LayerTypeICMPv6: p.Network += len(s.icmp6.Payload) - case layers.LayerTypeIPv6: - p.SrcIP = s.ip6.SrcIP.String() - p.DstIP = s.ip6.DstIP.String() - p.Network += len(s.ip6.Payload) - case layers.LayerTypeIPv4: p.SrcIP = s.ip4.SrcIP.String() p.DstIP = s.ip4.DstIP.String() p.Network += len(s.ip4.Payload) + case layers.LayerTypeIPv6: + p.SrcIP = s.ip6.SrcIP.String() + p.DstIP = s.ip6.DstIP.String() + p.Network += len(s.ip6.Payload) + case layers.LayerTypeTCP: p.SrcPort = strconv.Itoa(int(s.tcp.SrcPort)) p.DstPort = strconv.Itoa(int(s.tcp.DstPort)) @@ -199,7 +199,6 @@ func (s *Sniffer) read(src gopacket.ZeroCopyPacketDataSource, dst chan Packet, p p.Transport += len(s.udp.Payload) } } - select { case dst <- p: atomic.AddUint64(count, 1) @@ -228,19 +227,21 @@ func (s *Sniffer) Merge(p Packet, rpt report.Report) { // 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 - egress bool + 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, remoteIP, egress = p.SrcIP, p.DstIP, true + localIP, localPort, remoteIP, remotePort, egress = p.SrcIP, p.SrcPort, p.DstIP, p.DstPort, true case !srcLocal && dstLocal: - localIP, remoteIP, egress = p.DstIP, p.SrcIP, false + localIP, localPort, remoteIP, remotePort, egress = p.DstIP, p.DstPort, p.SrcIP, p.SrcPort, false case srcLocal && dstLocal: - localIP, remoteIP, egress = p.SrcIP, p.DstIP, true // loopback + 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 @@ -255,7 +256,9 @@ func (s *Sniffer) Merge(p Packet, rpt report.Report) { srcAdjacencyID = report.MakeAdjacencyID(srcNodeID) ) - rpt.Address.NodeMetadatas[srcNodeID] = report.MakeNodeMetadata() + if _, ok := rpt.Address.NodeMetadatas[srcNodeID]; !ok { + rpt.Address.NodeMetadatas[srcNodeID] = report.MakeNodeMetadata() + } emd := rpt.Address.EdgeMetadatas[edgeID] if emd.PacketCount == nil { @@ -282,12 +285,15 @@ func (s *Sniffer) Merge(p Packet, rpt report.Report) { // If we have ports, we can add to the endpoint topology, too. if p.SrcPort != "" && p.DstPort != "" { var ( - srcNodeID = report.MakeEndpointNodeID(s.hostID, localIP, p.SrcPort) - dstNodeID = report.MakeEndpointNodeID(s.hostID, remoteIP, p.DstPort) + srcNodeID = report.MakeEndpointNodeID(s.hostID, localIP, localPort) + dstNodeID = report.MakeEndpointNodeID(s.hostID, remoteIP, remotePort) edgeID = report.MakeEdgeID(srcNodeID, dstNodeID) srcAdjacencyID = report.MakeAdjacencyID(srcNodeID) ) - rpt.Endpoint.NodeMetadatas[srcNodeID] = report.MakeNodeMetadata() + + if _, ok := rpt.Endpoint.NodeMetadatas[srcNodeID]; !ok { + rpt.Endpoint.NodeMetadatas[srcNodeID] = report.MakeNodeMetadata() + } emd := rpt.Endpoint.EdgeMetadatas[edgeID] if emd.PacketCount == nil { diff --git a/render/render.go b/render/render.go index 86daa7ed9..e80de1781 100644 --- a/render/render.go +++ b/render/render.go @@ -207,6 +207,7 @@ func (m LeafMap) Render(rpt report.Report) RenderableNodes { if md, ok := t.EdgeMetadatas[edgeID]; ok { srcRenderableNode.EdgeMetadata.Merge(md) } + } nodes[srcRenderableID] = srcRenderableNode diff --git a/report/topology.go b/report/topology.go index 0327f35ad..c6f28e23f 100644 --- a/report/topology.go +++ b/report/topology.go @@ -32,8 +32,8 @@ type NodeMetadatas map[string]NodeMetadata // collect about a directed edge between two nodes in any topology. type EdgeMetadata struct { PacketCount *uint64 `json:"packet_count,omitempty"` - EgressByteCount *uint64 `json:"ingress_byte_count,omitempty"` - IngressByteCount *uint64 `json:"egress_byte_count,omitempty"` + EgressByteCount *uint64 `json:"egress_byte_count,omitempty"` + IngressByteCount *uint64 `json:"ingress_byte_count,omitempty"` MaxConnCountTCP *uint64 `json:"max_conn_count_tcp,omitempty"` }