Skip to content

Commit 09cacac

Browse files
authored
Paris traceroute (#54)
Add paris-traceroute support to traceroute-caller.
1 parent 2b147ee commit 09cacac

File tree

16 files changed

+576
-302
lines changed

16 files changed

+576
-302
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "vendor/libparistraceroute"]
2+
path = vendor/libparistraceroute
3+
url = https://github.com/libparistraceroute/libparistraceroute.git

Dockerfile

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.12 as build
1+
FROM golang:1.13 as build
22
ADD . /go/src/github.com/m-lab/traceroute-caller
33
ENV GOARCH amd64
44
ENV CGO_ENABLED 0
@@ -13,15 +13,25 @@ RUN chmod -R a+rx /go/bin/traceroute-caller
1313
FROM ubuntu:latest
1414
# Install all the standard packages we need and then remove the apt-get lists.
1515
RUN apt-get update && \
16-
apt-get install -y python python-pip make iproute2 coreutils autoconf && \
16+
apt-get install -y python python-pip make iproute2 coreutils autoconf libtool git build-essential && \
1717
apt-get clean && \
1818
rm -rf /var/lib/apt/lists/*
1919

2020
RUN ls -l
21-
RUN mkdir /source
22-
ADD ./vendor/scamper/ /source
23-
RUN chmod +x /source/scamper-cvs-20190916/configure
24-
WORKDIR /source/scamper-cvs-20190916/
21+
RUN mkdir /scamper-src
22+
ADD ./vendor/scamper/ /scamper-src
23+
RUN chmod +x /scamper-src/scamper-cvs-20190916/configure
24+
WORKDIR /scamper-src/scamper-cvs-20190916/
25+
RUN ./configure
26+
RUN make -j 8
27+
RUN make install
28+
RUN ldconfig
29+
30+
RUN mkdir /pt-src
31+
ADD ./vendor/libparistraceroute/ /pt-src
32+
WORKDIR /pt-src
33+
RUN mkdir m4
34+
RUN ./autogen.sh
2535
RUN ./configure
2636
RUN make -j 8
2737
RUN make install

caller.go

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import (
55
"context"
66
"flag"
77
"log"
8+
"os"
89
"sync"
910
"time"
1011

1112
"github.com/m-lab/traceroute-caller/connection"
13+
"github.com/m-lab/traceroute-caller/tracer"
1214

1315
"github.com/m-lab/go/flagx"
1416
"github.com/m-lab/go/rtx"
@@ -18,23 +20,31 @@ import (
1820
"github.com/m-lab/traceroute-caller/connectionlistener"
1921
"github.com/m-lab/traceroute-caller/connectionpoller"
2022
"github.com/m-lab/traceroute-caller/ipcache"
21-
"github.com/m-lab/traceroute-caller/scamper"
2223
)
2324

2425
var (
25-
scamperBin = flag.String("scamper.bin", "scamper", "path of scamper binary")
26-
scattachBin = flag.String("scamper.sc_attach", "sc_attach", "path of sc_attach binary")
27-
scwarts2jsonBin = flag.String("scamper.sc_warts2json", "sc_warts2json", "path of sc_warts2json binary")
26+
scamperBin = flag.String("scamper.bin", "scamper", "The path to the scamper binary.")
27+
scattachBin = flag.String("scamper.sc_attach", "sc_attach", "The path to the sc_attach binary.")
28+
scwarts2jsonBin = flag.String("scamper.sc_warts2json", "sc_warts2json", "The path to the sc_warts2json binary.")
2829
scamperCtrlSocket = flag.String("scamper.unixsocket", "/tmp/scamperctrl", "The name of the UNIX-domain socket that the scamper daemon should listen on")
30+
scamperTimeout = flag.Duration("scamper.timeout", 300*time.Second, "how long to wait to complete a scamper trace.")
31+
parisBin = flag.String("paris.bin", "paris-traceroute", "The path to the paris-traceroute binary.")
32+
parisTimeout = flag.Duration("paris.timeout", 60*time.Second, "how long to wait to complete a paris-traceroute trace.")
2933
outputPath = flag.String("outputPath", "/var/spool/scamper", "path of output")
3034
waitTime = flag.Duration("waitTime", 5*time.Second, "how long to wait between subsequent listings of open connections")
31-
eventsocketDryRun = flag.Bool("tcpinfo.eventsocket.dryrun", false, "Whether the eventsocket machinery should be turned on in print-only mode.")
3235
poll = flag.Bool("poll", true, "Whether the polling method should be used to see new connections.")
33-
scamperTimeout = flag.Duration("scamperTimeout", 300*time.Second, "how long to wait to complete a scamper trace.")
36+
tracerType = flagx.Enum{
37+
Options: []string{"paris-traceroute", "scamper"},
38+
Value: "scamper",
39+
}
3440

3541
ctx, cancel = context.WithCancel(context.Background())
3642
)
3743

44+
func init() {
45+
flag.Var(&tracerType, "tracetool", "Choose whether paris-traceroute or scamper should be used.")
46+
}
47+
3848
// Sample cmd:
3949
// go build
4050
// ./traceroute-caller --outputPath scamper_output
@@ -43,27 +53,40 @@ func main() {
4353

4454
flag.Parse()
4555
rtx.Must(flagx.ArgsFromEnv(flag.CommandLine), "Could not get args from environment")
56+
rtx.Must(os.MkdirAll(*outputPath, 0557), "Could not create data directory")
4657

4758
defer cancel()
4859

4960
promSrv := prometheusx.MustServeMetrics()
5061
defer promSrv.Shutdown(ctx)
5162

52-
daemon := scamper.Daemon{
53-
Binary: *scamperBin,
54-
AttachBinary: *scattachBin,
55-
Warts2JSONBinary: *scwarts2jsonBin,
56-
OutputPath: *outputPath,
57-
ControlSocket: *scamperCtrlSocket,
58-
ScamperTimeout: *scamperTimeout,
63+
var trace ipcache.Tracer
64+
switch tracerType.Value {
65+
case "scamper":
66+
daemon := &tracer.ScamperDaemon{
67+
Binary: *scamperBin,
68+
AttachBinary: *scattachBin,
69+
Warts2JSONBinary: *scwarts2jsonBin,
70+
OutputPath: *outputPath,
71+
ControlSocket: *scamperCtrlSocket,
72+
ScamperTimeout: *scamperTimeout,
73+
}
74+
go func() {
75+
daemon.MustStart(ctx)
76+
cancel()
77+
}()
78+
trace = daemon
79+
case "paris-traceroute":
80+
trace = &tracer.Paris{
81+
Binary: *parisBin,
82+
OutputPath: *outputPath,
83+
Timeout: *parisTimeout,
84+
}
5985
}
60-
go func() {
61-
daemon.MustStart(ctx)
62-
cancel()
63-
}()
6486

6587
wg := sync.WaitGroup{}
66-
cache := ipcache.New(ctx, &daemon, *ipcache.IPCacheTimeout, *ipcache.IPCacheUpdatePeriod)
88+
cache := ipcache.New(ctx, trace, *ipcache.IPCacheTimeout, *ipcache.IPCacheUpdatePeriod)
89+
6790
if *poll {
6891
wg.Add(1)
6992
go func(c *ipcache.RecentIPCache) {
@@ -84,11 +107,6 @@ func main() {
84107
go func() {
85108
connCreator, err := connection.NewCreator()
86109
rtx.Must(err, "Could not discover local IPs")
87-
esdaemon := daemon
88-
esdaemon.DryRun = *eventsocketDryRun
89-
if *eventsocketDryRun {
90-
cache = ipcache.New(ctx, &esdaemon, *ipcache.IPCacheTimeout, *ipcache.IPCacheUpdatePeriod)
91-
}
92110
connListener := connectionlistener.New(connCreator, cache)
93111
eventsocket.MustRun(ctx, *eventsocket.Filename, connListener)
94112
wg.Done()

caller_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ func TestMain(t *testing.T) {
2727
*prometheusx.ListenAddress = ":0"
2828
*scamperCtrlSocket = dir + "/scamper.sock"
2929
*waitTime = time.Nanosecond // Run through the loop a few times.
30+
*outputPath = dir
31+
tracerType.Value = "scamper"
3032
ctx, cancel = context.WithCancel(context.Background())
3133
go func() {
3234
time.Sleep(1 * time.Second)
@@ -44,7 +46,8 @@ func TestMainWithConnectionListener(t *testing.T) {
4446
*prometheusx.ListenAddress = ":0"
4547
*scamperCtrlSocket = dir + "/scamper.sock"
4648
*eventsocket.Filename = dir + "/events.sock"
47-
*eventsocketDryRun = true
49+
*outputPath = dir
50+
tracerType.Value = "paris-traceroute"
4851

4952
ctx, cancel = context.WithCancel(context.Background())
5053
go srv.Serve(ctx)

connectionlistener/connectionlistener_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ func (ft *fakeTracer) Trace(conn connection.Connection, t time.Time) (string, er
3838
return "Fake test Result", nil
3939
}
4040

41-
func (ft *fakeTracer) CreateCacheTest(conn connection.Connection, t time.Time, cachedTest string) {
41+
func (ft *fakeTracer) TraceFromCachedTrace(conn connection.Connection, t time.Time, cachedTest string) error {
4242
log.Println("Create cached test for: ", conn)
43-
return
43+
return nil
4444
}
4545

4646
func (*fakeTracer) DontTrace(conn connection.Connection, err error) {}

connectionpoller/connectionpoller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func parseSSLine(line string) (*connection.Connection, error) {
100100
type ssFinder struct{}
101101

102102
func (f *ssFinder) GetConnections() map[connection.Connection]struct{} {
103-
cmd := exec.Command(*ssBinary, "-e")
103+
cmd := exec.Command(*ssBinary, "-e", "-n")
104104
var out bytes.Buffer
105105
var stderr bytes.Buffer
106106
cmd.Stdout = &out

connectionpoller/connectionpoller_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,11 @@ func (tt *testTracer) Trace(conn connection.Connection, t time.Time) (string, er
130130
return "Fake Trace test", nil
131131
}
132132

133-
func (tt *testTracer) CreateCacheTest(conn connection.Connection, t time.Time, cachedTest string) {}
134-
func (tt *testTracer) DontTrace(conn connection.Connection, err error) {}
133+
func (tt *testTracer) TraceFromCachedTrace(conn connection.Connection, t time.Time, cachedTest string) error {
134+
return nil
135+
}
136+
137+
func (tt *testTracer) DontTrace(conn connection.Connection, err error) {}
135138

136139
type testFinder struct {
137140
}

ipcache/ipcache.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ var (
2121
// Tracer is the generic interface for all things that can perform a traceroute.
2222
type Tracer interface {
2323
Trace(conn connection.Connection, t time.Time) (string, error)
24-
CreateCacheTest(conn connection.Connection, t time.Time, cachedTest string)
24+
TraceFromCachedTrace(conn connection.Connection, t time.Time, cachedTest string) error
2525
DontTrace(conn connection.Connection, err error)
2626
}
2727

@@ -64,7 +64,7 @@ func (rc *RecentIPCache) Trace(conn connection.Connection) (string, error) {
6464
if cached {
6565
<-c.dataReady
6666
if c.err == nil {
67-
rc.tracer.CreateCacheTest(conn, time.Now(), c.data)
67+
rc.tracer.TraceFromCachedTrace(conn, time.Now(), c.data)
6868
return c.data, nil
6969
}
7070
rc.tracer.DontTrace(conn, c.err)
@@ -86,10 +86,10 @@ func (rc *RecentIPCache) GetCacheLength() int {
8686

8787
// New creates and returns a RecentIPCache. It also starts up a background
8888
// goroutine that scrubs the cache.
89-
func New(ctx context.Context, tracer Tracer, ipCacheTimeout, ipCacheUpdatePeriod time.Duration) *RecentIPCache {
89+
func New(ctx context.Context, trace Tracer, ipCacheTimeout, ipCacheUpdatePeriod time.Duration) *RecentIPCache {
9090
m := &RecentIPCache{
9191
cache: make(map[string]*cachedTest),
92-
tracer: tracer,
92+
tracer: trace,
9393
}
9494
go func() {
9595
ticker := time.NewTicker(ipCacheUpdatePeriod)

ipcache/ipcache_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ func (tf *testTracer) Trace(conn connection.Connection, t time.Time) (string, er
2626
return "Fake trace test " + conn.RemoteIP, nil
2727
}
2828

29-
func (tf *testTracer) CreateCacheTest(conn connection.Connection, t time.Time, cachedTest string) {
29+
func (tf *testTracer) TraceFromCachedTrace(conn connection.Connection, t time.Time, cachedTest string) error {
3030
tf.cctest++
31+
return nil
3132
}
3233

3334
func (tf *testTracer) DontTrace(conn connection.Connection, err error) {
@@ -130,9 +131,10 @@ func (pt *pausingTracer) Trace(conn connection.Connection, t time.Time) (string,
130131
return "Trace to " + conn.RemoteIP, nil
131132
}
132133

133-
func (pt *pausingTracer) CreateCacheTest(conn connection.Connection, t time.Time, cachedTest string) {
134+
func (pt *pausingTracer) TraceFromCachedTrace(conn connection.Connection, t time.Time, cachedTest string) error {
134135
randomDelay()
135136
atomic.AddInt64(&pt.successes, 1)
137+
return nil
136138
}
137139

138140
func (pt *pausingTracer) DontTrace(conn connection.Connection, err error) {

0 commit comments

Comments
 (0)