fix out-of-bounds read when creating a multiplexed tracer

This commit is contained in:
Marten Seemann
2020-07-20 12:16:48 +07:00
parent 4e4c71c1b9
commit bd2b4e3e71
2 changed files with 62 additions and 50 deletions

View File

@@ -17,7 +17,7 @@ func NewMultiplexedTracer(tracers ...Tracer) Tracer {
return nil return nil
} }
if len(tracers) == 1 { if len(tracers) == 1 {
return tracers[1] return tracers[0]
} }
return &tracerMultiplexer{tracers} return &tracerMultiplexer{tracers}
} }

View File

@@ -12,63 +12,75 @@ import (
var _ = Describe("Tracing", func() { var _ = Describe("Tracing", func() {
Context("Tracer", func() { Context("Tracer", func() {
var ( It("returns a nil tracer if no tracers are passed in", func() {
tracer Tracer Expect(NewMultiplexedTracer()).To(BeNil())
tr1, tr2 *MockTracer
)
BeforeEach(func() {
tr1 = NewMockTracer(mockCtrl)
tr2 = NewMockTracer(mockCtrl)
tracer = NewMultiplexedTracer(tr1, tr2)
}) })
It("multiplexes the TracerForConnection call", func() { It("returns the raw tracer if only one tracer is passed in", func() {
tr1.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3}) tr := NewMockTracer(mockCtrl)
tr2.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3}) tracer := NewMultiplexedTracer(tr)
tracer.TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3}) Expect(tracer).To(BeAssignableToTypeOf(&MockTracer{}))
}) })
It("uses multiple connection tracers", func() { Context("tracing events", func() {
ctr1 := NewMockConnectionTracer(mockCtrl) var (
ctr2 := NewMockConnectionTracer(mockCtrl) tracer Tracer
tr1.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}).Return(ctr1) tr1, tr2 *MockTracer
tr2.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}).Return(ctr2) )
tr := tracer.TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3})
ctr1.EXPECT().LossTimerCanceled()
ctr2.EXPECT().LossTimerCanceled()
tr.LossTimerCanceled()
})
It("handles tracers that return a nil ConnectionTracer", func() { BeforeEach(func() {
ctr1 := NewMockConnectionTracer(mockCtrl) tr1 = NewMockTracer(mockCtrl)
tr1.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}).Return(ctr1) tr2 = NewMockTracer(mockCtrl)
tr2.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}) tracer = NewMultiplexedTracer(tr1, tr2)
tr := tracer.TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}) })
ctr1.EXPECT().LossTimerCanceled()
tr.LossTimerCanceled()
})
It("returns nil when all tracers return a nil ConnectionTracer", func() { It("multiplexes the TracerForConnection call", func() {
tr1.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3}) tr1.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3})
tr2.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3}) tr2.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3})
Expect(tracer.TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3})).To(BeNil()) tracer.TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3})
}) })
It("traces the PacketSent event", func() { It("uses multiple connection tracers", func() {
remote := &net.UDPAddr{IP: net.IPv4(4, 3, 2, 1)} ctr1 := NewMockConnectionTracer(mockCtrl)
hdr := &Header{DestConnectionID: ConnectionID{1, 2, 3}} ctr2 := NewMockConnectionTracer(mockCtrl)
f := &MaxDataFrame{MaximumData: 1337} tr1.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}).Return(ctr1)
tr1.EXPECT().SentPacket(remote, hdr, ByteCount(1024), []Frame{f}) tr2.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}).Return(ctr2)
tr2.EXPECT().SentPacket(remote, hdr, ByteCount(1024), []Frame{f}) tr := tracer.TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3})
tracer.SentPacket(remote, hdr, 1024, []Frame{f}) ctr1.EXPECT().LossTimerCanceled()
}) ctr2.EXPECT().LossTimerCanceled()
tr.LossTimerCanceled()
})
It("traces the PacketDropped event", func() { It("handles tracers that return a nil ConnectionTracer", func() {
remote := &net.UDPAddr{IP: net.IPv4(4, 3, 2, 1)} ctr1 := NewMockConnectionTracer(mockCtrl)
tr1.EXPECT().DroppedPacket(remote, PacketTypeRetry, ByteCount(1024), PacketDropDuplicate) tr1.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3}).Return(ctr1)
tr2.EXPECT().DroppedPacket(remote, PacketTypeRetry, ByteCount(1024), PacketDropDuplicate) tr2.EXPECT().TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3})
tracer.DroppedPacket(remote, PacketTypeRetry, 1024, PacketDropDuplicate) tr := tracer.TracerForConnection(PerspectiveServer, ConnectionID{1, 2, 3})
ctr1.EXPECT().LossTimerCanceled()
tr.LossTimerCanceled()
})
It("returns nil when all tracers return a nil ConnectionTracer", func() {
tr1.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3})
tr2.EXPECT().TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3})
Expect(tracer.TracerForConnection(PerspectiveClient, ConnectionID{1, 2, 3})).To(BeNil())
})
It("traces the PacketSent event", func() {
remote := &net.UDPAddr{IP: net.IPv4(4, 3, 2, 1)}
hdr := &Header{DestConnectionID: ConnectionID{1, 2, 3}}
f := &MaxDataFrame{MaximumData: 1337}
tr1.EXPECT().SentPacket(remote, hdr, ByteCount(1024), []Frame{f})
tr2.EXPECT().SentPacket(remote, hdr, ByteCount(1024), []Frame{f})
tracer.SentPacket(remote, hdr, 1024, []Frame{f})
})
It("traces the PacketDropped event", func() {
remote := &net.UDPAddr{IP: net.IPv4(4, 3, 2, 1)}
tr1.EXPECT().DroppedPacket(remote, PacketTypeRetry, ByteCount(1024), PacketDropDuplicate)
tr2.EXPECT().DroppedPacket(remote, PacketTypeRetry, ByteCount(1024), PacketDropDuplicate)
tracer.DroppedPacket(remote, PacketTypeRetry, 1024, PacketDropDuplicate)
})
}) })
}) })