Skip to content

Commit

Permalink
Merge pull request #17 from exaring/refactor/prober
Browse files Browse the repository at this point in the history
Make prober independent of config package.
  • Loading branch information
awlx authored Dec 3, 2019
2 parents aa3ef39 + 71c17fd commit 21899c5
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 162 deletions.
27 changes: 22 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,32 @@ func main() {
os.Exit(1)
}

confSrc, err := cfg.GetConfiguredSrcAddr()
if err != nil {
log.Errorf("Unable to get configured src addr: %v", err)
os.Exit(1)
}

probers := make([]*prober.Prober, 0)
for i := range cfg.Paths {
for j := range cfg.Classes {
log.Infof("Starting prober for path %q class %q", cfg.Paths[i].Name, cfg.Classes[j].Name)
p, err := prober.New(cfg, cfg.Paths[i], prober.TOS{
Value: cfg.Classes[j].TOS,
LabelValue: cfg.Classes[j].Name,
},
[]prober.Label{})
p, err := prober.New(prober.Config{
BasePort: *cfg.BasePort,
ConfiguredSrcAddr: confSrc,
SrcAddrs: config.GenerateAddrs(*cfg.SrcRange),
Hops: cfg.PathToProberHops(cfg.Paths[i]),
StaticLabels: []prober.Label{},
TOS: prober.TOS{
Name: cfg.Classes[j].Name,
Value: cfg.Classes[j].TOS,
},
PPS: *cfg.Paths[i].PPS,
PayloadSizeBytes: *cfg.Paths[i].PayloadSizeBytes,
MeasurementLengthMS: *cfg.Paths[i].MeasurementLengthMS,
TimeoutMS: *cfg.Paths[i].TimeoutMS,
})

if err != nil {
log.Errorf("Unable to get new prober: %v", err)
os.Exit(1)
Expand Down
78 changes: 78 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package config

import (
"bytes"
"encoding/binary"
"fmt"
"net"

"github.com/exaring/matroschka-prober/pkg/prober"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -231,3 +234,78 @@ func (c *Config) GetConfiguredSrcAddr() (net.IP, error) {

return nil, nil
}

// PathToProberHops generates prober hops
func (c *Config) PathToProberHops(pathCfg Path) []prober.Hop {
res := make([]prober.Hop, 0)

for i := range pathCfg.Hops {
for j := range c.Routers {
if pathCfg.Hops[i] != c.Routers[j].Name {
continue
}

h := prober.Hop{
Name: c.Routers[j].Name,
DstRange: GenerateAddrs(c.Routers[j].DstRange),
SrcRange: GenerateAddrs(c.Routers[j].SrcRange),
}
res = append(res, h)
}
}

return res
}

// GenerateAddrs returns a list of all IPs in addrRange
func GenerateAddrs(addrRange string) []net.IP {
_, n, err := net.ParseCIDR(addrRange)
if err != nil {
panic(err)
}

baseAddr := getCIDRBase(*n)
c := maskAddrCount(*n)
ret := make([]net.IP, c)

for i := uint32(0); i < c; i++ {
ret[i] = net.IP(uint32Byte(baseAddr + i%c))
}

return ret
}

func getCIDRBase(n net.IPNet) uint32 {
return uint32b(n.IP)
}

func uint32b(data []byte) (ret uint32) {
buf := bytes.NewBuffer(data)
binary.Read(buf, binary.BigEndian, &ret)
return
}

func getNthAddr(n net.IPNet, i uint32) net.IP {
baseAddr := getCIDRBase(n)
c := maskAddrCount(n)
return net.IP(uint32Byte(baseAddr + i%c))
}

func maskAddrCount(n net.IPNet) uint32 {
ones, bits := n.Mask.Size()
if ones == bits {
return 1
}

x := uint32(1)
for i := ones; i < bits; i++ {
x = x * 2
}
return x
}

func uint32Byte(data uint32) (ret []byte) {
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, data)
return buf.Bytes()
}
26 changes: 18 additions & 8 deletions pkg/prober/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func (p *Prober) Collect(ch chan<- prometheus.Metric) {
}

func (p *Prober) labels() []string {
keys := make([]string, len(p.staticLabels)+2)
for i, l := range p.staticLabels {
keys := make([]string, len(p.cfg.StaticLabels)+2)
for i, l := range p.cfg.StaticLabels {
keys[i] = l.Key
}

Expand All @@ -45,16 +45,26 @@ func (p *Prober) labels() []string {
}

func (p *Prober) labelValues() []string {
values := make([]string, len(p.staticLabels)+2)
for i, l := range p.staticLabels {
values := make([]string, len(p.cfg.StaticLabels)+2)
for i, l := range p.cfg.StaticLabels {
values[i] = l.Value
}

values[len(values)-2] = p.tos.LabelValue
values[len(values)-1] = strings.Join(p.path.Hops, "-")
values[len(values)-2] = p.cfg.TOS.Name
values[len(values)-1] = strings.Join(p.getHopNames(), "-")
return values
}

func (p *Prober) getHopNames() []string {
ret := make([]string, len(p.cfg.Hops))

for i, x := range p.cfg.Hops {
ret[i] = x.Name
}

return ret
}

func (p *Prober) collectSent(ch chan<- prometheus.Metric, m *measurement.Measurement) {
desc := prometheus.NewDesc(metricPrefix+"packets_sent", "Sent packets", p.labels(), nil)
ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, float64(m.Sent), p.labelValues()...)
Expand Down Expand Up @@ -85,8 +95,8 @@ func (p *Prober) collectRTTAvg(ch chan<- prometheus.Metric, m *measurement.Measu
}

func (p *Prober) lastFinishedMeasurement() int64 {
measurementLengthNS := int64(*p.path.MeasurementLengthMS) * int64(time.Millisecond)
timeoutNS := int64(*p.path.TimeoutMS) * int64(time.Millisecond)
measurementLengthNS := int64(p.cfg.MeasurementLengthMS) * int64(time.Millisecond)
timeoutNS := int64(p.cfg.TimeoutMS) * int64(time.Millisecond)
nowNS := p.clock.Now().UnixNano()
ts := nowNS - timeoutNS - measurementLengthNS
return ts - ts%measurementLengthNS
Expand Down
13 changes: 6 additions & 7 deletions pkg/prober/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"testing"
"time"

"github.com/exaring/matroschka-prober/pkg/config"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -32,9 +31,9 @@ func TestLastFinishedMeasurement(t *testing.T) {
clock: mockClock{
t: time.Unix(1542556558, 0),
},
path: config.Path{
MeasurementLengthMS: uint64ptr(1000),
TimeoutMS: uint64ptr(200),
cfg: Config{
MeasurementLengthMS: 1000,
TimeoutMS: 200,
},
},
expected: 1542556556000000000,
Expand All @@ -45,9 +44,9 @@ func TestLastFinishedMeasurement(t *testing.T) {
clock: mockClock{
t: time.Unix(1542556558, 250000000),
},
path: config.Path{
MeasurementLengthMS: uint64ptr(1000),
TimeoutMS: uint64ptr(200),
cfg: Config{
MeasurementLengthMS: 1000,
TimeoutMS: 200,
},
},
expected: 1542556557000000000,
Expand Down
14 changes: 7 additions & 7 deletions pkg/prober/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ const (
)

func (p *Prober) getSrcAddrHop(hop int, seq uint64) net.IP {
return p.hops[hop-1].srcRange[seq%uint64(len(p.hops[hop-1].srcRange))]
return p.cfg.Hops[hop-1].SrcRange[seq%uint64(len(p.cfg.Hops[hop-1].SrcRange))]
}

func (p *Prober) getDstAddr(hop int, seq uint64) net.IP {
return p.hops[hop].dstRange[seq%uint64(len(p.hops[hop].dstRange))]
return p.cfg.Hops[hop].DstRange[seq%uint64(len(p.cfg.Hops[hop].DstRange))]
}

func (p *Prober) craftPacket(pr *probe) ([]byte, error) {
Expand All @@ -32,12 +32,12 @@ func (p *Prober) craftPacket(pr *probe) ([]byte, error) {
ComputeChecksums: true,
}

l := make([]gopacket.SerializableLayer, 0, (len(p.hops)-1)*2+5)
l := make([]gopacket.SerializableLayer, 0, (len(p.cfg.Hops)-1)*2+5)
l = append(l, &layers.GRE{
Protocol: layers.EthernetTypeIPv4,
})

for i := range p.hops {
for i := range p.cfg.Hops {
if i == 0 {
continue
}
Expand All @@ -47,7 +47,7 @@ func (p *Prober) craftPacket(pr *probe) ([]byte, error) {
DstIP: p.getDstAddr(i, pr.Seq),
Version: 4,
Protocol: layers.IPProtocolGRE,
TOS: p.tos.Value,
TOS: p.cfg.TOS.Value,
TTL: ttl,
})

Expand All @@ -58,11 +58,11 @@ func (p *Prober) craftPacket(pr *probe) ([]byte, error) {

// Create final UDP packet that will return
ip := &layers.IPv4{
SrcIP: p.getSrcAddrHop(len(p.hops), pr.Seq),
SrcIP: p.getSrcAddrHop(len(p.cfg.Hops), pr.Seq),
DstIP: p.localAddr,
Version: 4,
Protocol: layers.IPProtocolUDP,
TOS: p.tos.Value,
TOS: p.cfg.TOS.Value,
TTL: ttl,
}
l = append(l, ip)
Expand Down
Loading

0 comments on commit 21899c5

Please sign in to comment.