예제 #1
0
파일: main.go 프로젝트: neviim/scope
// discover reads reports from a collector and republishes them on the
// publisher, while scanning the reports for IPs to connect to. Only addresses
// in the network topology of the report are considered. IPs listed in fixed
// are always skipped.
func discover(c collector, p publisher, fixed []string) {
	lastSeen := map[string]time.Time{}

	avoid := makeAvoid(fixed)

	for r := range c.Reports() {
		// log.Printf("got a report")
		p.Publish(r)

		var (
			now       = time.Now()
			localNets = render.LocalNetworks(r)
		)

		for _, adjacent := range r.Address.Adjacency {
			for _, a := range adjacent {
				ip := report.AddressIDAddresser(a) // address id -> IP
				if ip == nil {
					continue
				}

				addr := ip.String()
				if _, ok := avoid[addr]; ok {
					continue
				}
				// log.Printf("potential address: %v (via %s)", addr, src)
				if _, ok := lastSeen[addr]; !ok {
					if interestingAddress(localNets, addr) {
						log.Printf("discovery %v: potential probe address", addr)
						c.Add(addressToDial(addr))
					} else {
						log.Printf("discovery %v: non-probe address", addr)
					}
				}

				// We always add addr to lastSeen[], even if it's a non-local
				// address. This way they are part of the normal timeout logic,
				// and we won't analyze the address again until it re-appears
				// after a timeout.
				lastSeen[addr] = now
			}
		}

		for addr, last := range lastSeen {
			if now.Sub(last) > trafficTimeout {
				// Timeout can be for a non-local address, which we didn't
				// connect to. In that case the RemoveAddress() call won't do
				// anything.
				log.Printf("discovery %v: traffic timeout", addr)
				delete(lastSeen, addr)
				c.Remove(addressToDial(addr))
			}
		}
	}
}
예제 #2
0
func TestReportLocalNetworks(t *testing.T) {
	r := report.MakeReport()
	r.Merge(report.Report{Host: report.Topology{NodeMetadatas: report.NodeMetadatas{
		"nonets": report.NewNodeMetadata(map[string]string{}),
		"foo":    report.NewNodeMetadata(map[string]string{host.LocalNetworks: "10.0.0.1/8 192.168.1.1/24 10.0.0.1/8 badnet/33"}),
	}}})
	want := report.Networks([]*net.IPNet{
		mustParseCIDR("10.0.0.1/8"),
		mustParseCIDR("192.168.1.1/24"),
	})
	have := render.LocalNetworks(r)
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
예제 #3
0
func TestReportLocalNetworks(t *testing.T) {
	r := report.MakeReport().Merge(report.Report{
		Host: report.Topology{
			Nodes: report.Nodes{
				"nonets": report.MakeNode(),
				"foo": report.MakeNode().WithSets(report.Sets{
					host.LocalNetworks: report.MakeStringSet(
						"10.0.0.1/8", "192.168.1.1/24", "10.0.0.1/8", "badnet/33"),
				}),
			},
		},
	})
	want := report.Networks([]*net.IPNet{
		mustParseCIDR("10.0.0.1/8"),
		mustParseCIDR("192.168.1.1/24"),
	})
	have := render.LocalNetworks(r)
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}