mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
trace packets that are sent outside of a connection
This commit is contained in:
parent
f10894a1ce
commit
0c551c893c
9 changed files with 99 additions and 0 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
protocol "github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
wire "github.com/lucas-clemente/quic-go/internal/wire"
|
||||
logging "github.com/lucas-clemente/quic-go/logging"
|
||||
)
|
||||
|
||||
|
@ -48,6 +49,18 @@ func (mr *MockTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 interface
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket mocks base method
|
||||
func (m *MockTracer) SentPacket(arg0 net.Addr, arg1 *wire.Header, arg2 protocol.ByteCount, arg3 []logging.Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket indicates an expected call of SentPacket
|
||||
func (mr *MockTracerMockRecorder) SentPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockTracer)(nil).SentPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// TracerForConnection mocks base method
|
||||
func (m *MockTracer) TracerForConnection(arg0 protocol.Perspective, arg1 protocol.ConnectionID) logging.ConnectionTracer {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -68,6 +68,8 @@ const (
|
|||
Encryption1RTT EncryptionLevel = protocol.Encryption1RTT
|
||||
// Encryption0RTT is the 0-RTT encryption level
|
||||
Encryption0RTT EncryptionLevel = protocol.Encryption0RTT
|
||||
// EncryptionNone is no encryption
|
||||
EncryptionNone EncryptionLevel = protocol.EncryptionUnspecified
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -85,6 +87,7 @@ type Tracer interface {
|
|||
// If nil is returned, tracing will be disabled for this connection.
|
||||
TracerForConnection(p Perspective, odcid ConnectionID) ConnectionTracer
|
||||
|
||||
SentPacket(net.Addr, *Header, ByteCount, []Frame)
|
||||
DroppedPacket(net.Addr, PacketType, ByteCount, PacketDropReason)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ package logging
|
|||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
protocol "github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
wire "github.com/lucas-clemente/quic-go/internal/wire"
|
||||
net "net"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
@ -46,6 +47,18 @@ func (mr *MockTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 interface
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket mocks base method
|
||||
func (m *MockTracer) SentPacket(arg0 net.Addr, arg1 *wire.Header, arg2 protocol.ByteCount, arg3 []Frame) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SentPacket", arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SentPacket indicates an expected call of SentPacket
|
||||
func (mr *MockTracerMockRecorder) SentPacket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockTracer)(nil).SentPacket), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// TracerForConnection mocks base method
|
||||
func (m *MockTracer) TracerForConnection(arg0 protocol.Perspective, arg1 protocol.ConnectionID) ConnectionTracer {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -32,6 +32,12 @@ func (m *tracerMultiplexer) TracerForConnection(p Perspective, odcid ConnectionI
|
|||
return newConnectionMultiplexer(connTracers...)
|
||||
}
|
||||
|
||||
func (m *tracerMultiplexer) SentPacket(remote net.Addr, hdr *Header, size ByteCount, frames []Frame) {
|
||||
for _, t := range m.tracers {
|
||||
t.SentPacket(remote, hdr, size, frames)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *tracerMultiplexer) DroppedPacket(remote net.Addr, typ PacketType, size ByteCount, reason PacketDropReason) {
|
||||
for _, t := range m.tracers {
|
||||
t.DroppedPacket(remote, typ, size, reason)
|
||||
|
|
|
@ -56,6 +56,15 @@ var _ = Describe("Tracing", func() {
|
|||
})
|
||||
|
||||
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)
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
|
||||
"go.opencensus.io/stats"
|
||||
|
@ -65,6 +66,16 @@ func (t *tracer) TracerForConnection(p logging.Perspective, _ logging.Connection
|
|||
return newConnTracer(t, p)
|
||||
}
|
||||
|
||||
func (t *tracer) SentPacket(_ net.Addr, hdr *logging.Header, _ protocol.ByteCount, _ []logging.Frame) {
|
||||
stats.RecordWithTags(
|
||||
context.Background(),
|
||||
[]tag.Mutator{
|
||||
tag.Upsert(keyPacketType, packetType(logging.PacketTypeFromHeader(hdr)).String()),
|
||||
},
|
||||
sentPackets.M(1),
|
||||
)
|
||||
}
|
||||
|
||||
func (t *tracer) DroppedPacket(net.Addr, logging.PacketType, logging.ByteCount, logging.PacketDropReason) {
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ func (t *tracer) TracerForConnection(p logging.Perspective, odcid protocol.Conne
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *tracer) SentPacket(net.Addr, *logging.Header, protocol.ByteCount, []logging.Frame) {}
|
||||
func (t *tracer) DroppedPacket(net.Addr, logging.PacketType, protocol.ByteCount, logging.PacketDropReason) {
|
||||
}
|
||||
|
||||
|
|
18
server.go
18
server.go
|
@ -553,6 +553,9 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
|
|||
// append the Retry integrity tag
|
||||
tag := handshake.GetRetryIntegrityTag(buf.Bytes(), hdr.DestConnectionID)
|
||||
buf.Write(tag[:])
|
||||
if s.config.Tracer != nil {
|
||||
s.config.Tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(buf.Len()), nil)
|
||||
}
|
||||
_, err = s.conn.WriteTo(buf.Bytes(), remoteAddr)
|
||||
return err
|
||||
}
|
||||
|
@ -627,6 +630,9 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han
|
|||
|
||||
replyHdr.Log(s.logger)
|
||||
wire.LogFrame(s.logger, ccf, true)
|
||||
if s.config.Tracer != nil {
|
||||
s.config.Tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(raw)), []logging.Frame{ccf})
|
||||
}
|
||||
_, err := s.conn.WriteTo(raw, remoteAddr)
|
||||
return err
|
||||
}
|
||||
|
@ -638,6 +644,18 @@ func (s *baseServer) sendVersionNegotiationPacket(p *receivedPacket, hdr *wire.H
|
|||
s.logger.Debugf("Error composing Version Negotiation: %s", err)
|
||||
return
|
||||
}
|
||||
if s.config.Tracer != nil {
|
||||
s.config.Tracer.SentPacket(
|
||||
p.remoteAddr,
|
||||
&wire.Header{
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: hdr.SrcConnectionID,
|
||||
SrcConnectionID: hdr.DestConnectionID,
|
||||
},
|
||||
protocol.ByteCount(len(data)),
|
||||
nil,
|
||||
)
|
||||
}
|
||||
if _, err := s.conn.WriteTo(data, p.remoteAddr); err != nil {
|
||||
s.logger.Debugf("Error sending Version Negotiation: %s", err)
|
||||
}
|
||||
|
|
|
@ -261,6 +261,7 @@ var _ = Describe("Server", func() {
|
|||
Version: serv.config.Versions[0],
|
||||
}, make([]byte, protocol.MinInitialPacketSize))
|
||||
packet.remoteAddr = raddr
|
||||
tracer.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
|
||||
serv.handlePacket(packet)
|
||||
Eventually(done).Should(BeClosed())
|
||||
})
|
||||
|
@ -284,6 +285,7 @@ var _ = Describe("Server", func() {
|
|||
Version: serv.config.Versions[0],
|
||||
}, make([]byte, protocol.MinInitialPacketSize))
|
||||
packet.remoteAddr = raddr
|
||||
tracer.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).MaxTimes(1)
|
||||
serv.handlePacket(packet)
|
||||
Eventually(done).Should(BeClosed())
|
||||
})
|
||||
|
@ -379,6 +381,12 @@ var _ = Describe("Server", func() {
|
|||
Version: 0x42,
|
||||
}, make([]byte, protocol.MinInitialPacketSize))
|
||||
packet.remoteAddr = &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
|
||||
tracer.EXPECT().SentPacket(packet.remoteAddr, gomock.Any(), gomock.Any(), nil).Do(func(_ net.Addr, replyHdr *logging.Header, _ logging.ByteCount, _ []logging.Frame) {
|
||||
Expect(replyHdr.IsLongHeader).To(BeTrue())
|
||||
Expect(replyHdr.Version).To(BeZero())
|
||||
Expect(replyHdr.SrcConnectionID).To(Equal(destConnID))
|
||||
Expect(replyHdr.DestConnectionID).To(Equal(srcConnID))
|
||||
})
|
||||
serv.handlePacket(packet)
|
||||
var write mockPacketConnWrite
|
||||
Eventually(conn.dataWritten).Should(Receive(&write))
|
||||
|
@ -402,6 +410,12 @@ var _ = Describe("Server", func() {
|
|||
}
|
||||
packet := getPacket(hdr, make([]byte, protocol.MinInitialPacketSize))
|
||||
packet.remoteAddr = &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
|
||||
tracer.EXPECT().SentPacket(packet.remoteAddr, gomock.Any(), gomock.Any(), nil).Do(func(_ net.Addr, replyHdr *logging.Header, _ logging.ByteCount, _ []logging.Frame) {
|
||||
Expect(replyHdr.Type).To(Equal(protocol.PacketTypeRetry))
|
||||
Expect(replyHdr.SrcConnectionID).ToNot(Equal(hdr.DestConnectionID))
|
||||
Expect(replyHdr.DestConnectionID).To(Equal(hdr.SrcConnectionID))
|
||||
Expect(replyHdr.Token).ToNot(BeEmpty())
|
||||
})
|
||||
serv.handlePacket(packet)
|
||||
var write mockPacketConnWrite
|
||||
Eventually(conn.dataWritten).Should(Receive(&write))
|
||||
|
@ -429,6 +443,16 @@ var _ = Describe("Server", func() {
|
|||
packet := getPacket(hdr, make([]byte, protocol.MinInitialPacketSize))
|
||||
packet.data = append(packet.data, []byte("coalesced packet")...) // add some garbage to simulate a coalesced packet
|
||||
packet.remoteAddr = &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
|
||||
tracer.EXPECT().SentPacket(packet.remoteAddr, gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ net.Addr, replyHdr *logging.Header, _ logging.ByteCount, frames []logging.Frame) {
|
||||
Expect(replyHdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||
Expect(replyHdr.SrcConnectionID).To(Equal(hdr.DestConnectionID))
|
||||
Expect(replyHdr.DestConnectionID).To(Equal(hdr.SrcConnectionID))
|
||||
Expect(frames).To(HaveLen(1))
|
||||
Expect(frames[0]).To(BeAssignableToTypeOf(&wire.ConnectionCloseFrame{}))
|
||||
ccf := frames[0].(*logging.ConnectionCloseFrame)
|
||||
Expect(ccf.IsApplicationError).To(BeFalse())
|
||||
Expect(ccf.ErrorCode).To(Equal(qerr.InvalidToken))
|
||||
})
|
||||
serv.handlePacket(packet)
|
||||
var write mockPacketConnWrite
|
||||
Eventually(conn.dataWritten).Should(Receive(&write))
|
||||
|
@ -740,6 +764,7 @@ var _ = Describe("Server", func() {
|
|||
p := getInitialWithRandomDestConnID()
|
||||
hdr, _, _, err := wire.ParsePacket(p.data, 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
tracer.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||
serv.handlePacket(p)
|
||||
var reject mockPacketConnWrite
|
||||
Eventually(conn.dataWritten).Should(Receive(&reject))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue